KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

07. 超时以后,最重要的是承认“不知道” — keel 龙骨

客户端调用配置服务,等待 10 秒后超时。以下三种事实都会产生同一个客户端现象:

客户端调用配置服务,等待 10 秒后超时。以下三种事实都会产生同一个客户端现象:

  1. 请求根本没有到达服务端;
  2. 请求到达,但服务端在提交前失败;
  3. 服务端已经提交,成功响应没有返回。

因此 timeout 描述的是观察结果,不是业务结果。

Failure 和 Unknown 的区别

failed   已有权威证据表明动作没有完成
unknown  当前证据不足,动作可能完成也可能没有完成

把 unknown 写成 failed 会诱导重试;写成 succeeded 会制造假事实。正确做法是保存未知状态和可查询线索。

对账从读取事实开始

配置动作可以按资源和期望值查询:

本地 Command: set pool_limit=40, expected version=cfg-7
外部现状: pool_limit=40, version=cfg-8, change_id=command-123
判断: 本动作已生效 -> succeeded

仅比较最终值有时不够。另一个操作者也可能把值改成 40,所以外部系统最好保存 command_id、幂等键或变更事件 ID。

Reconciler 的三种结论

flowchart TD
    U[unknown receipt] --> Q[按 external_reference / resource 查询]
    Q -->|找到同一 command 的成功记录| S[succeeded]
    Q -->|明确未提交且可安全重试| F[failed / retryable]
    Q -->|证据冲突或不可查询| M[manual_review]

对账器不重新执行动作。它只读取权威系统并更新本地认识。

Read-your-own-writes 也可能暂时失效

外部系统采用最终一致性时,刚提交的写入可能尚未出现在读副本。一次查不到不能立刻断言未生效。对账策略需要:

运行未知结果实验

python courses/advanced/real-world-execution/course/project/examples/06_unknown_and_reconcile.py

模拟 Adapter 在提交后丢失响应。Gateway 首先记录 unknown;Reconciler 随后按 command ID 查到外部变更记录,才把状态改成 succeeded。配置不能被执行第二次。

检查理解

下一章:不能回滚的世界,怎样收拾部分成功?

进入 keel 阅读