feat: support durable task cancellation without foreign keys
This commit is contained in:
@@ -97,7 +97,7 @@ if err != nil {
|
||||
fmt.Println(cancelled.Task.State)
|
||||
```
|
||||
|
||||
取消重报必须保留第一次取消时的 expected_revision,不能将响应中的新版本塞回同一幂等请求。当前只取消 WAITING 且不归属流程的任务。若此前存在未知效果,取消结果为 NEEDS_REVIEW,不能解释为已撤销外部效果。
|
||||
取消重报必须保留第一次取消时的 expected_revision,不能将响应中的新版本塞回同一幂等请求。已支持独立任务和计划任务的等待、预占、运行和核查状态;运行中受理返回 202,任务状态仍为 RUNNING,需另行查询最终状态。完整语义和运行示例见 [取消契约](../api/cancellation.md)。若此前存在未知效果,本次确认取消不能清除它。
|
||||
|
||||
业务错误返回 *orbit.APIError,支持 errors.As 转为 *orbit.HTTPError 查看状态。健康错误或无法识别的网关错误使用 *orbit.HTTPError,不带未知响应正文。网络/上下文错误按标准库错误返回;超时并不能证明服务端没有提交。
|
||||
|
||||
@@ -179,4 +179,4 @@ task=<任务ID> state=SUCCEEDED attempts=1 evidence=1 reason=RESULT_CONFLICT dis
|
||||
|
||||
## 7. 后续交付
|
||||
|
||||
P2 已提供底层协议、[自动 Worker 运行器及示例](worker-runtime.md) 与历史查询,并通过 [Schema 及进程故障阶段验收](../reports/phase-2.md);P3 已实现 [安全重试与示例](../api/retries.md) 和 [计划调度与示例](../api/schedules.md),运行中取消、资源配额和结果订阅继续开发;P4–P5 提供流程构建发布、信号、等待、轮询与人工恢复。每项随实现同步交付可运行示例及异常回归。
|
||||
P2 已提供底层协议、[自动 Worker 运行器及示例](worker-runtime.md) 与历史查询,并通过 [Schema 及进程故障阶段验收](../reports/phase-2.md);P3 已实现 [安全重试](../api/retries.md)、[计划调度](../api/schedules.md) 和 [运行中取消及示例](../api/cancellation.md),资源配额和结果订阅继续开发;P4–P5 提供流程构建发布、信号、等待、轮询与人工恢复。每项随实现同步交付可运行示例及异常回归。
|
||||
|
||||
@@ -72,6 +72,7 @@ SDK 的 Run 每个实例只能调用一次,包括已经正常退出的实例
|
||||
## 4. 执行、续租与恢复
|
||||
|
||||
- 只有 Start 当前授权有效才调用处理器;同进程中的已知尝试最多调用一次。重复确认与重新连接只核对控制操作。
|
||||
- 自动 Worker 开启取消通知,收到匹配尝试的通知或 Resume/Start/Renew 返回取消意图后,立即取消处理器 context,原因是 ErrTaskCancellationRequested,停止续租并继续上报真实结果。该函数未返回前仍占本地物理槽。
|
||||
- 处理器在独立 goroutine 执行,网络控制由事件循环管理;每连接当前只保留一个执行器控制请求在途。不同处理器可以并行,控制请求顺序与业务并发上限分开。
|
||||
- 会话心跳按服务端 TTL 的三分之一计算,上限 5 秒。任务续租按当前保守租约剩余时间的三分之一安排,下限 20 毫秒;服务器仍限制总截止与单次尝试时限。
|
||||
- 每个处理器的租约监视器独立取消 context,断网或控制请求阻塞也不会延长本地执行权限。最新会话若缩短租约,监视器会采用较短期限。已到期的处理器不会被后续确认复活。
|
||||
@@ -91,12 +92,15 @@ Run 的重连恢复同一次控制操作。平台的 [安全重试](../api/retri
|
||||
| panic / runtime.Goexit | UNKNOWN / HANDLER_PANIC 或 HANDLER_ABORTED |
|
||||
| 非法 JSON、超限结果、不支持数值或嵌套 | UNKNOWN / INVALID_HANDLER_RESULT |
|
||||
| 处理器因租约取消返回错误 | UNKNOWN / LEASE_LOST |
|
||||
| 收到任务取消后返回 `&orbit.WorkerCancellationConfirmed{Details:...}` | CANCELLED;只用于确认本次停止且无未结清效果,历史未知效果仍需核查 |
|
||||
| 报告到达时租约已失效、或结果与权威状态冲突 | 服务端可只保存 EVIDENCE_ONLY;不把证据计为任务成功 |
|
||||
|
||||
原始异常和 panic 内容不写入结果或通知。Result/Details 最多 256 KiB,应优先使用对象引用。SDK 保留精确数字文本,并按服务端数字范围及完整帧的嵌套上限预检,避免产生永远无法接受的报告。
|
||||
|
||||
普通网络错误不能证明副作用未发生,因此不会自动解释为明确失败。UNKNOWN 由服务端结合真实幂等声明决定是否重试;迟到证据不能清除历史不确定效果。完整规则及可运行示例见 [安全重试](../api/retries.md)。
|
||||
|
||||
任务取消也不能自动解释为已停止。普通 ctx.Err() 仍报告 UNKNOWN;只有业务明确确认后才返回 WorkerCancellationConfirmed。已经成功时返回真实成功结果,不能因为 context 同时取消而覆盖成功。开始 ACK 丢失且处理器尚未调用时,SDK 重连核对意图后可以报告本次未执行;用法、升级顺序和完整示例见 [取消契约](../api/cancellation.md)。
|
||||
|
||||
## 6. 退出与故障边界
|
||||
|
||||
取消 Run context 后,运行器请求持久化排空,收集排空 ACK 之前已派发的工作,继续为在途任务续租并确认结果。进程应等待 Run 返回,而不是取消 context 后立即退出。
|
||||
|
||||
@@ -66,6 +66,7 @@ defer conn.Close()
|
||||
| `client.DialWorker` | registration | *WorkerConnection | 握手后尚未启用派发 |
|
||||
| `conn.Capacity` | messageID、WorkerCapacity | WorkerWelcome | 总容量覆盖值;同时续期会话 |
|
||||
| `conn.NextAssignment` | ctx | WorkerAssignment | 只表示预占,不能直接运行处理器 |
|
||||
| `conn.NextCancellation` | ctx | WorkerCancellation | 注册 CancellationNotifications=true 后持续读取,只停止匹配 task/attempt/epoch 的处理器 |
|
||||
| `conn.Start` | messageID、WorkerAttempt | WorkerCommandResult | 持久化开始后确认,检查 Lease 的当前授权 |
|
||||
| `conn.Renew` | messageID、WorkerAttempt | WorkerCommandResult | 新续租用新消息;原消息只核对原操作 |
|
||||
| `conn.Finish` | messageID、WorkerFinish | WorkerCommandResult | 区分权威结果 APPLIED 与证据 EVIDENCE_ONLY |
|
||||
@@ -92,7 +93,7 @@ defer cancel()
|
||||
// 将 work 与业务输入传给处理器,不传执行秘密。
|
||||
```
|
||||
|
||||
`ExecutionDeadline()` 只认可 `Active=true`、`State=RUNNING` 和仍未到期的本地期限。SDK 以服务端 `lease_until-server_time` 为窗口,扣除从调用开始起的全部耗时(含等待写入)及 250 毫秒安全余量,用本地单调时钟表示。数据库墙钟与客户端相差一天也不会额外获得一天授权。
|
||||
`ExecutionDeadline()` 只认可 `Active=true`、`State=RUNNING`、CancelRequestedAt 为空和仍未到期的本地期限。取消后 Active 仍可为 true,用于报告当前结果,不授予继续执行权。SDK 以服务端 `lease_until-server_time` 为窗口,扣除从调用开始起的全部耗时(含等待写入)及 250 毫秒安全余量,用本地单调时钟表示。数据库墙钟与客户端相差一天也不会额外获得一天授权。
|
||||
|
||||
只有 SDK 控制响应会设置内部本地期限;自行构造/JSON 解码的 WorkerLease 不会得到执行授权。旧 start 回执即使包含历史 RUNNING 和未来 lease_until,也不能越过当前 Lease 的失效判断。
|
||||
|
||||
@@ -107,6 +108,7 @@ defer cancel()
|
||||
| Finish 请求结果不明 | 保留原 finishID、Outcome、Result、ErrorCode,重连核对后原样重报 |
|
||||
| 明确业务成功 | `WorkerSucceeded`,不带 ErrorCode |
|
||||
| 可确认的业务失败 | `WorkerFailed`,带稳定 ErrorCode |
|
||||
| 收到取消意图,确认已停止且本次无未结清效果 | `WorkerCancelled`,带稳定 ErrorCode;普通 context 错误不足以证明 |
|
||||
| 超时、失联或不能确认外部效果 | `WorkerUnknown`,带稳定 ErrorCode;默认转核查,仅 IDEMPOTENT 且预算允许时自动重试 |
|
||||
| `Disposition=EVIDENCE_ONLY` | 内容已留作证据;不能当作任务成功,另查 GetTask 的权威状态 |
|
||||
|
||||
@@ -118,6 +120,7 @@ Result 是不超过 256 KiB 的非 null JSON,可传对象引用;原始异常
|
||||
- 传输中断返回 `ErrWorkerDisconnected`;消息格式/版本不兼容返回 `ErrWorkerProtocol`;主动关闭为 `ErrWorkerClosed`;超时/取消支持标准 context 错误。
|
||||
- 最多 32 个在途控制请求,达到上限返回 `ErrWorkerBusy`,请求未发送。同一消息 ID 已在途时也拒绝第二个并发等待者。
|
||||
- 派发缓冲最多 8 条;读取不及时会以 `ErrWorkerBackpressure` 关闭连接。持久化预占由服务端恢复,不无限积压内存。
|
||||
- 取消通知另有 32 条缓冲,满时同样关闭连接;NextCancellation 的等待 context 取消不会断开连接。重连后仍要通过 Resume/Renew 核对取消意图,通知不代替持久化状态。完整契约与先升级服务端的要求见 [运行中取消](../api/cancellation.md)。
|
||||
- 控制操作最长 10 秒,包含排队、发送与等待 ACK;调用方 context 可以缩短。已发送后取消/超时会关闭连接,操作是否提交需用原身份核对。
|
||||
- `NextAssignment` 的 context 取消只停止等待,不关闭连接。已关闭连接不会继续交付缓冲中的派发。
|
||||
- 入站单帧最多 512 KiB;读空闲期限 60 秒。需要调用方持续心跳,不能用此期限代替默认 45 秒会话期限。
|
||||
|
||||
Reference in New Issue
Block a user