指南 · 第 12 章
受控并发与原子性
1.7.1 七个实验接口、所有权、效果限制、事务与取消边界,以及可运行示例。
1.7.1 的范围与开启方式
默认生效:长期 Context 环境参与 GC roots;Stream 关闭释放负载引用;任务子进程独立配额失败恢复与清理;portable no-replace 使用独占发布。语言规范保持 1.0,Database 保持 1.0.0。
HHY_CONCURRENCY_EXPERIMENTS=1 hhy run --engine bytecode atomic-state.hhy
HHY_CONCURRENCY_EXPERIMENTS=1 hhy run --engine ast atomic-state.hhy
hhy contracts --format json上述变量只对单条命令生效。PowerShell 可先设置 $env:HHY_CONCURRENCY_EXPERIMENTS="1",运行后 Remove-Item Env:HHY_CONCURRENCY_EXPERIMENTS。dry-run 只记录契约,返回 Null,不执行回调,也不验证真实结果。
原子性与一致性保证矩阵
| 资源域 | 提交与失败 | 边界 |
|---|---|---|
| AtomicState | 所属 Runtime 同步发布整个候选值;提交前失败保留旧值 | 不跨 Runtime / Worker 共享 |
| 单文件 | 稳定 sidecar 锁内原子替换;发布后持久性可能未知 | 仅协作写者;不覆盖跨文件事务或网络文件系统 |
| 数据库 | 服务器 COMMIT;区分回滚与未知提交 | 隔离级别、SQL、约束和幂等共同决定一致性 |
| task_map | 全部成功后按序返回;失败终止并回收直接任务 | 不回滚子任务已发生的外部效果 |
| 普通变量 | 保持既有语义与隔离捕获 | 没有自动升级为原子变量 |
七个实验接口
函数atomic_state#
atomic_state(data)创建 Runtime/PID 所有者绑定的状态句柄。
函数atomic_read#
atomic_read(state)读取不可变快照。
函数atomic_update#
atomic_update(state, callback)校验纯回调候选值并同步发布;提交前错误保留旧值。
函数atomic_close#
atomic_close(state)关闭句柄;关闭后访问或再次关闭均失败。
函数atomic_file_update#
atomic_file_update(path, timeout, callback)锁内读改写已有普通文件;timeout 仅限制等锁时间。
函数transaction_strict#
transaction_strict(config, options?, callback)SQL 绑定当前 tx;捕获错误仍禁止提交;未知提交需对账。
函数task_map#
task_map(data, parallelism, result_limit, callback)隔离进程执行,按输入顺序返回 List,限制直接子任务和接收结果。
状态更新与句柄所有权
let state = atomic_state({left: 0, right: 100})
fn transfer(old) { {left: old.left + 1, right: old.right - 1} }
atomic_update(state, transfer)
print(atomic_read(state))
atomic_close(state)示例完成后 left 为 1、right 为 99。atomic_update 返回新值,atomic_read 读取不可变快照。数据只允许 Null、Bool、Int、有限 Float、String 和递归 List/Map,深度上限 128。Function、Stream 和句柄不允许进入状态。
效果契约与提交状态机
strict_capability 分为 pure、bound_transaction 和 external,白名单以 Runtime contracts 为准。严格回调禁止 I/O、任务、Stream、时钟、随机、import、变量赋值(包括局部 mut)和嵌套严格作用域。数据库回调额外允许绑定当前 tx 的 query/execute。第三方扩展不能自行声明 pure 绕过限制。
ACTIVE -> COMMITTING -> COMMITTED
| |----> ABORTED
| `----> UNKNOWN
`----> ABORTED单文件协作更新
fn increment(text) { encode_json(to_int(text) + 1) }
atomic_file_update(path(args[0]), 3s, increment) |> printprintf '0' > /tmp/hhy-counter.txt
HHY_CONCURRENCY_EXPERIMENTS=1 hhy run atomic-file.hhy /tmp/hhy-counter.txt文件必须预先存在;回调 String → String。等待锁的 Duration 须大于 0 且不超过 300s,不是回调执行期限。所有写者必须遵守同一路径和 <target>.hhy-lock 协议。拒绝符号链接、多硬链接和 .hhy-lock 目标名;活跃写者期间不要删除锁文件。不保证保留 inode、ACL 或扩展属性。
受限数据库事务与持久幂等
import database
let cfg = read_text(path(args[0])) |> parse_json
let n = cfg |> transaction_strict { tx ->
database.execute(tx, "UPDATE counters SET n = n + 1 WHERE id = 1", [])
return database.query(tx, "SELECT n FROM counters WHERE id = 1", []).rows[0].n
}
print(n)先安装 Database 1.0.0 扩展,准备已有 counters 表及 id=1、n 为整数的记录,再以数据库配置 JSON 路径作为 args[0] 运行。配置遵循数据库扩展文档;凭据留在本地配置中。options 可设置已有 isolation/read_only。
回调不能使用其他 tx、连接池、流式句柄、手动 commit/savepoint,也不能返回 tx(包括嵌套结果)。MySQL 隐式提交语句被拒绝。服务器存储过程和触发器内部效果仍由服务器配置决定,Runtime 无法证明任意 SQL 无外部效果。
数据库安装与配置Database 独立版本 1.0.0有界任务、取消与原 parallel
let results = [1, 2, 3] |> task_map(2, 1mib) { n -> n * 2 }
print(results)示例按输入顺序得到 [2, 4, 6]。task_map 接收 List 并急切返回 List,使用隔离子进程;parallel 保留已有 Stream 行为。并行度为正整数且受 Runtime 限额约束。结果预算为 1b–256mib,限制累计已接收的序列化结果。
验收证据与仍未承诺的能力
- 本地 69 个引擎/配置用例;每引擎 10,000 次提交;GC、owner、配额与效果拒绝测试。
- 80 次竞争文件增量;native/portable no-replace 竞争;MySQL/PostgreSQL 32 请求、8 个幂等键及丢失提交回包对账。
- 120 秒长稳及 100,000 请求 Web 验收通过;不是 24 小时长稳、真实断电或通用共享内存线性化证明。
- 四平台 CI 与发行验收通过;Windows 为 MSYS2 工件,不包含 Database 扩展。
- HHY_BYTECODE_BINDING_CACHE=1 和 HHY_STREAM_SOURCE_FUSION=1 仍独立默认关闭;当前证据不支持默认开启或普遍加速声明。
