Files
orbit/docs/16-workflow-recovery.md

80 lines
8.6 KiB
Markdown
Raw 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 人工核查与接续
状态:执行核查、步骤结论、解除核查、TASK/POLL新激活、PENDING等待接续和SIGNAL/TIMER换代已实现,并接入[六类公共恢复API及SDK](api/workflow-recovery.md)。当前详情与管理审计可读,完整历史和生产验收继续按[计划](08-development-plan.md)推进。
## 1. 六类操作
[内部服务](../weave/recovery/service.go)要求显式`workflows:recover`权限,普通Worker、任务核查和流程暂停权限均不自动包含它。六个方法都接收认证身份、实例ID、稳定幂等键和命令,命名空间与操作者从认证取得。
| 方法 | 作用 | 不会自动发生的事情 |
| --- | --- | --- |
| ReviewTask | 核实本实例历史激活拥有的NEEDS_REVIEW任务,写入SUCCEEDED/FAILED、明确执行已结束和证据 | 不把查询请求成功解释成业务成功,不解除步骤或实例核查 |
| ResolveStep | 将当前待核查/失败/取消叶子步骤核实为SUCCEEDED或FAILED,保存符合固定契约的逻辑结果 | 不重新执行旧任务,不清除实例核查或原停止意图 |
| ContinuePoll | 根据已处理的权威PENDING结果恢复原等待,保留轮次和间隔 | 不重查同轮,不改写原Inbox处置,不解除实例核查 |
| RearmWait | 在原截止内为独立SIGNAL/TIMER建立新等待代次 | 不延长原截止,不丢弃未消费信号,不重跑成功步骤 |
| Continue | 在当前证据和步骤状态允许时解除实例核查,保存根接续 | 不解除显式paused,不延长截止,不撤销取消或失败结清 |
| RetryStep | 为TASK或POLL建立新的激活和关联任务,继续消耗原任务或原业务轮尝试预算 | 不重跑成功步骤,不改变输入/业务关联,POLL恢复不另起业务轮次 |
查询请求、外部业务结果和流程接续是不同事实。例如,查询任务核实为成功但返回PENDING,仍不能将POLL步骤核实为成功;POLL成功结论必须通过固定映射分类为SUCCEEDED。未知执行须先完成ReviewTask,再等待新版本结果进入内部Inbox并消费,才能确认步骤结论。
## 2. 身份、版本与证据
所有命令携带:
| 字段 | 约束 |
| --- | --- |
| expected_revision | 当前实例revision,JSON十进制字符串;必须大于0,不使用control_revision代替证据版本 |
| reason | 1至1024个Unicode字符,非空白,不含NUL |
| evidence_ref | 1至512个无空白或控制字符的Unicode字符;受控证据引用,平台不访问该地址 |
ReviewTask还要求`task_id`、`expected_task_revision`、`execution_settled=true`、SUCCEEDED/FAILED结论和非null JSON结果。声明表示全部历史外部执行已结束且不会继续产生效果;租约失效和UNKNOWN本身不能证明这一点。
ResolveStep和RetryStep都要求固定`step_key`、当前`activation_id`及`expected_step_revision`。前者要求`execution_settled=true`,后者要求`safe_to_retry=true`。ContinuePoll要求`pending_confirmed=true`,RearmWait要求`wait_verified=true`;这两项还要求StepDecision。Continue要求`review_resolved=true`,服务端仍独立检查当前图、历史任务与来源事件,不把声明作为绕过检查的开关。
同键相同命令返回首次冻结回执;同键不同内容冲突。回执恢复仍检查当前凭据和固定定义引用的全部队列权限。后台新增事实使原实例revision失效,新键携带旧版本会冲突;原键可继续核对已提交决定。每个成功人工操作同时递增revision和control_revision,防止旧暂停/继续命令覆盖人工恢复后的控制状态。
## 3. 事务与历史
认证 → 应用额度 → 管理操作身份 → 固定版本的排序队列 → 实例 → 门控 → 子项。操作只针对NEEDS_REVIEW实例;新决定要求内部Inbox不存在PENDING或QUARANTINED记录。尚未消费的事实应先消费,损坏来源不能靠人工声明直接放行。
核查状态、额度、实例/步骤、门控、必要根接续、审计和幂等回执同事务。ReviewTask在所有这些写入完成后发布新的Pulse结果事件,结果流锁最后获取,之后不能再锁另一任务。执行审计与流程审计使用不同操作身份,流程审计明确引用执行审计,二者同事务提交。结果流写入失败时全部回滚。
步骤核查先校验所有历史任务的双向归属,再检查该步骤全部历史任务均已知结清、无有效尝试和未释放许可。兄弟分支仍可收集自己的在途结果;Continue还会拒绝任何历史未知结果及当前未解决的步骤。关联检查按命名空间和固定队列执行,不使用数据库外键。
ResolveStep保存当前激活的新管理结论,审计记录前一状态、前一输出和新结果摘要。Pulse原成功/失败结果不因此改写,执行尝试、旧事件、等待和查询轮次记录均保留。真正重新执行时才由RetryStep创建新激活,旧激活及旧任务结果保持原样,旧激活迟到结果只留痕。
## 4. TASK重试预算
TASK恢复规则如下。要求没有取消或失败停止意图,实例和原任务绝对截止尚未到达,相关历史执行均已知失败或取消。核实实际尝试行数、任务attempt_count、连续激活序号、retry_of链、固定处理器/输入/队列/优先级和策略一致性。
- 新激活sequence递增;新任务retry_of指向前一任务,同一原任务只允许一个直接后继。
- 新max_attempts = 固定定义max_attempts − 全部历史激活已用尝试数;首次尝试也计入。
- 新任务沿用首次激活的绝对deadline_at、最晚开始时间、精确输入、business_key与concurrency_key,不因人工操作重新计时。
- 激活总数也不超过原max_attempts,避免反复取消尚未开始的任务而无限创建零尝试激活。
- 原预算耗尽时拒绝新激活;业务关联键不自动提供幂等,接入方须在固定输入中保存正确的外部业务操作身份,并提供安全重试证据。
- 新任务受当前应用和队列配额约束;满额或审计失败不能留下新激活、孤立任务或多扣额度。
创建新任务后实例仍处于核查,门控保持关闭。操作者确认其他事项已处理后调用Continue,才允许新任务取得执行授权;原paused仍为true时还需正常RESUME。
POLL跨激活恢复已实现,保留原业务轮、同轮剩余尝试、查询总截止和该轮原任务截止;成功返回PENDING的轮次不能人工重查。附属最终信号等待沿用原契约/关联/截止并更换代次,详见[查询恢复](17-workflow-poll-recovery.md)。核查后已确认PENDING的显式等待接续与独立SIGNAL/TIMER等待重建已实现,见[等待恢复](18-workflow-wait-recovery.md)。
## 5. 停止与到期
存在原stop_kind时,核查可消除未知事实,但Continue只返回CANCELLING并接续原停止目标,门控继续关闭;停止运行器核验所有工作结清后才进入CANCELLED或FAILED。后来核实某一步成功也不能撤销先前已提交的停止意图。
无停止意图且原实例已过期时,Continue拒绝启动新工作。可以继续保存核查证据、确认步骤结论,并通过已有CANCEL和停止结清路径结束实例。TIMER成功核查还要求原等待时长确实已到,成功输出必须为显式null,不能人为提前满足时间条件。
## 6. 内部调用顺序
| 场景 | 顺序 |
| --- | --- |
| TASK效果未知,核实成功 | 读取当前实例/任务 → ReviewTask(SUCCEEDED) → 等待内部结果消费 → 读取当前版本 → ResolveStep(SUCCEEDED) → Continue → 后台接续 |
| TASK已确认失败,原预算仍有余量 | 读取当前实例/步骤/激活 → RetryStep → 核对新任务及原截止 → Continue → Worker执行新任务 |
| POLL请求失败且仍有预算 | RetryStep → 核对同业务轮和剩余尝试 → Continue;结果PENDING才按原间隔开下一轮 |
| POLL次数耗尽,人工取得最终结果 | 核实历史请求均已结束 → ResolveStep(符合固定成功映射的结果) → Continue;原used_rounds不改变 |
| 取消后出现UNKNOWN | ReviewTask → 等待消费 → ResolveStep → Continue → 原取消结清;不创建后继工作 |
以上内部操作已通过[公共恢复API及SDK](api/workflow-recovery.md)提供,六类真实服务场景保留相同证据与版本要求。
[存储专项](../internal/storage/mysql/workflow_recovery_integration_test.go)、[实际进程测试](../internal/storage/mysql/workflow_runtime_process_integration_test.go)和[阶段报告](reports/phase-5-recovery.md)记录验证范围。本阶段不替代生产数据库高可用、灾难恢复和容量验收。