Files
orbit/docs/18-workflow-wait-recovery.md

56 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Weave 等待核查与恢复
状态:ContinuePoll和RearmWait已实现,并已接入[公共恢复HTTP及独立SDK](api/workflow-recovery.md)。均遵守[人工恢复权限、版本、证据及原键规则](16-workflow-recovery.md)。本页说明内部持久化语义,完整历史和生产验收继续按[计划](08-development-plan.md)推进。
## 1. 两类操作
| 方法 | 适用事实 | 持久化结果 |
| --- | --- | --- |
| ContinuePoll | 当前最后查询任务已确定成功、结果为 PENDING,且对应权威 Inbox 已处理 | 保留当前激活和原业务轮,恢复 WAITING;到原间隔后才允许下一轮 |
| RearmWait | 独立 SIGNAL/TIMER 仍在原截止内,需要重建等待代次 | 关闭旧等待,创建新激活和新等待;保留首次输入、契约、关联键与截止 |
这两项操作都只针对 NEEDS_REVIEW 实例,不解除实例核查、显式暂停或执行门控。完成必要的其他核查后再调用 Continue;原 paused 为 true 时仍需 RESUME。已有取消或失败停止目标时拒绝恢复等待。
共同要求:显式 `workflows:recover`、最新实例 revision、步骤 revision、当前 activation_id、稳定操作键、原因和证据;拒绝未消费或隔离 Inbox,检查历史任务归属及已结束执行。兄弟分支可以继续收集在途结果,但恢复操作不能把其未知事实解释为完成。相同键返回原冻结回执,仍检查当前凭据与队列权限。
## 2. 已确认 PENDING 的接续
`ContinuePollInput` 在 StepDecision 基础上要求 `pending_confirmed=true`。该声明不能制造查询结果:服务端读取当前最后任务,要求 SUCCEEDED、无未知效果,并找到同版本、同激活的 PROCESSED Inbox。重新核验快照、原事件、任务/步骤/固定队列/尝试归属,结果还必须与当前权威任务结果一致并通过固定 PENDING 映射。
典型场景是:请求 UNKNOWN → ReviewTask 核实为 SUCCEEDED / PENDING → 内部结果消费 → ContinuePoll → Continue → 按原间隔开启下一业务轮。ReviewTask 本身不会清除步骤核查;不能通过 RetryStep 重查已经成功返回 PENDING 的同一轮。
接续保留:
- 原激活、已用业务轮数、查询总截止及实例总截止。
- 原任务、实际尝试、UNKNOWN 证据、原事件和原 Inbox 处置。
- 下一查询时间为 `min(该权威 PENDING 结果事件时间 + 原 interval_ms, 原查询截止)`。人工核查产生的新结果使用其确认事件时间,不能伪装为更早的外部时间。
- 不创建任务或消耗新轮次。时钟到期且门控/配额允许后才创建下一轮,该轮获得固定定义的完整单轮尝试策略。
已用轮次达到 max_rounds、查询或实例截止已到、原结果不为 PENDING、有未结清执行时拒绝。原请求尝试预算已经耗尽但结果后来被确认为 PENDING,并不消耗额外同轮请求;仍可在剩余业务轮次与查询期限内接续。
接续审计保存来源事件/版本、当前激活、轮次、步骤版本、原结清状态、下一查询时间与固定截止。时钟及最终信号运行器接受这条不可变证明,不改写原 Inbox 的 STEP_ALREADY_SETTLED 等历史处置。当前记录与证明不符时停止推进。
## 3. POLL 的附属最终信号
ContinuePoll 恢复同一个查询激活,因此信号目标代次不变;已拒绝或已消费的旧信号不会重新变为 PENDING。当前等待必须尚未到原截止、没有已选中的最终赢家,且没有当前代次未消费的信号。WAITING 或因先前查询核查而关闭的 CANCELLED 等待可恢复 WAITING,原状态写入管理审计。
如果已有最终赢家,不能用“仍在处理”声明覆盖它,应核查冲突事实。真正重查原请求的 RetryStep 则创建新激活并更换信号代次,两条路径见[查询重试约定](17-workflow-poll-recovery.md)。
## 4. SIGNAL/TIMER 的新代次
`RearmWaitInput` 在 StepDecision 基础上要求 `wait_verified=true`。当前步骤仅允许 WAITING、NEEDS_REVIEW、FAILED 或 CANCELLED;成功步骤不能重新等待。服务端核验完整连续激活历史,最多32个等待激活,包含首次等待;新激活不提供新的时间预算。
- 新 sequence = 旧 sequence + 1;首次输入、信号契约、精确关联键和原等待截止不变。
- 旧 WAITING 激活关闭为 CANCELLED,旧等待也关闭;已有失败/核查激活保留原状态及输出。它们继续由审计和历史关联追踪,不能误解为整个流程取消。
- 当前代次存在 PENDING 信号时拒绝重建,先处理已有事实。已匹配赢家不能被新代次绕过。
- 新等待没有赢家;旧代次后续信号被记录为 STALE_ACTIVATION,调用方须读取新代次后发送新信号。
- TIMER 始终以首次激活时间加固定 delay_ms 计时,重建和人工成功核查都不能提前满足时长或从新创建时间重算。等待或实例截止已到时拒绝重建。
新激活、旧等待结清、新等待、检查点、步骤版本、管理审计和原键回执同事务。审计失败全部回滚;本操作不创建 Pulse 任务,不占业务执行许可。恢复后仍等待显式 Continue 解除核查。
## 5. 实现与验收边界
复用现有激活、等待、查询状态、Inbox 和不可变审计表,没有新增迁移或持久化字段。仍为35个实体、305个带中文注释的直接持久化字段,无外键和级联删除。
实现见[等待重建](../internal/storage/mysql/workflow_wait_rearm.go)、[PENDING 接续与审计证明](../internal/storage/mysql/workflow_poll_continue.go)和[恢复服务](../weave/recovery/service.go)。验证范围见[本阶段报告](reports/phase-5-wait-recovery.md)。本机单 MySQL 与多控制进程回归不能替代生产数据库切换、备份恢复、容量及 RPO/RTO 验收。