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

8.2 KiB
Raw Blame History

Weave 人工核查与接续

状态:内部Go服务已提供执行核查、步骤结论确认、解除核查,以及TASK/POLL新激活重试。POLL跨激活预算与附属信号换代见查询恢复。公共HTTP、独立SDK和通用接入示例尚未交付;独立SIGNAL/TIMER等待重建继续实现。完整交付继续按开发计划推进。

1. 四类操作

内部服务要求显式workflows:recover权限,普通Worker、任务核查和流程暂停权限均不自动包含它。四个方法都接收认证身份、实例ID、稳定幂等键和命令,命名空间与操作者从认证取得。

方法 作用 不会自动发生的事情
ReviewTask 核实本实例历史激活拥有的NEEDS_REVIEW任务,写入SUCCEEDED/FAILED、明确执行已结束和证据 不把查询请求成功解释成业务成功,不解除步骤或实例核查
ResolveStep 将当前待核查/失败/取消叶子步骤核实为SUCCEEDED或FAILED,保存符合固定契约的逻辑结果 不重新执行旧任务,不清除实例核查或原停止意图
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。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的轮次不能人工重查。附属最终信号等待沿用原契约/关联/截止并更换代次,详见查询恢复。核查后已确认PENDING的显式等待接续仍需补齐;独立SIGNAL/TIMER逻辑结论可核查,等待重建仍待实现。

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 → 原取消结清;不创建后继工作

这些是内部服务流程说明,公共接入方目前不能调用未开放的HTTP路由或SDK。后续接口文档和可运行场景须覆盖相同证据与版本要求。

存储专项、实际进程测试和阶段报告记录验证范围。本阶段不替代生产数据库高可用、灾难恢复和容量验收。