Files
orbit/docs/15-workflow-controls.md

64 lines
7.1 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 控制与停止结清
状态:暂停、继续、取消与后台失败/取消结清已实现,并通过[公共控制API及SDK](api/workflows.md#4-暂停继续与取消)调用。人工恢复另见[恢复API](api/workflow-recovery.md)。当前功能回归不等同于生产验收。
## 1. 控制操作
[内部控制契约](../weave/control/service.go)使用`Apply(token, workflowID, idempotencyKey, input)`,显式授权`workflows:control`。每次读取当前命名空间、固定定义版本及其全部队列权限,原键恢复也重新核验权限。actor由认证凭据确定,输入只包含以下字段:
| 字段 | 语义 |
| --- | --- |
| operation | PAUSE、RESUME或CANCEL |
| expected_control_revision | 调用者观察到的控制版本,正整数,对外JSON为十进制字符串 |
| reason | 必填操作原因,最多1024个Unicode字符,写入不可变审计 |
后台结果会增加实例revision,不能使操作者观察到的control_revision失效。成功控制操作同时增加两个版本;同键相同内容返回首次冻结回执,不再次增加版本或改时间。同键不同内容冲突,其他键携带过期控制版本也冲突。新操作不接受终态实例;已提交原键仍可恢复原回执。
认证 → 应用额度 → 原操作身份 → 排序队列 → 实例 → 门控的持锁顺序与受理、运行器一致。控制标记、版本、门控、必要的根检查点、事件、审计和回执同事务提交。审计失败时整个操作回滚。
## 2. 暂停与继续
PAUSE设置实例paused并关闭Pulse执行门控。已创建但尚未开始的任务不能新领取或取得开始授权;已经获得开始授权的尝试保留许可,按原租约继续上报。暂停与开始竞争由同一个应用/队列/门控事务顺序裁决。
暂停期间继续保存任务结果、信号与到期事实,不启动新步骤或新查询轮次;待推进工作保存根检查点。RESUME仅解除paused,并保存根接续;实例处于核查或已有停止意图时,门控仍关闭。它不清除未知结果、不撤回取消、不改变固定定义,也不重置截止、轮次或尝试预算。
已暂停时使用新键再次PAUSE、未暂停时RESUME、已接受用户取消后使用新键再次CANCEL都返回状态冲突;网络未确认时应使用原键核对。原控制回执不会因为稍后的后台结果变化而变成当前视图,最新状态用实例Get读取。
## 3. 首次停止意图
停止意图与执行状态独立保存,进入NEEDS_REVIEW后仍能继续结清其他已发出的工作。
| 字段 | 语义 |
| --- | --- |
| stop_kind | CANCEL为用户请求,FAILURE为固定FAIL_AFTER_SETTLED策略触发;首次保存后不覆盖 |
| stop_requested_at | 首次停止意图的数据库时间,不随重报、核查或后来的控制操作变化 |
| cancel_requested_at | 用户显式请求取消的时间;自动失败结清不冒充用户请求 |
用户取消先提交时,最终按CANCEL目标结清;失败策略先触发时,后来的用户取消仍保留FAILURE目标,最终已知结清后为FAILED。两个时间和操作审计都保留,不用后到命令改写早先失败事实。
REVIEW策略继续保留核查状态和已发出结果;FAIL_AFTER_SETTLED在失败或核查条件出现时冻结停止意图,阻止新工作并请求其他分支结束。未知效果、非法结果和冲突证据始终保留NEEDS_REVIEW,不能为进入终态自动判定业务成功或失败。
## 4. 结清过程
停止使用既有ROOT检查点恢复。每个短事务最多发出一个Pulse任务取消,保持结果流锁取得之后不再锁另一任务;步骤收尾最多32项,超出保存根接续。候选由数据库到期索引读取,多个节点竞争仍只提交一次状态变化。
1. 核对任务实际所有者、激活、步骤、队列、门控及POLL轮次,不能仅凭gate_id授权取消。未开始的任务复用Pulse取消规则立即结清;执行中的任务只记录取消意图,保留执行许可。
2. 收集内部Inbox结果。已成功步骤及输出保留;已知失败或取消保留实际状态;未知结果转核查。查询成功返回PENDING时,停止中的POLL结清为取消,不再发下一轮请求。
3. 尚未激活步骤记为SKIPPED,不创建新任务。取消前可靠受理的匹配信号先保留为已收到事实;新的信号保存WORKFLOW_STOPPING拒绝。未结清的纯等待由停止运行器关闭,稍后超时扫描不能覆盖已提交的停止意图。
4. 全部活动叶子结清后才关闭尚未完成的组合节点。终态前核验全部历史任务双向归属、结果确认、未结束尝试和未释放许可;不只看当前步骤或当前激活。
5. 全部工作已知结清且没有核查条件时,根与实例进入FAILED或CANCELLED,关闭门控、清除待续并保存审计。存在未知或核查条件时保持NEEDS_REVIEW和原停止意图,平台已无有效执行授权时不再空转,后续人工核查操作负责接续;租约失效或UNKNOWN不证明外部执行确实已经结束。
历史核验按原有限流程上限限制为最多10000条任务元数据,使用一次集合查询和索引关联,避免逐任务数据库往返。门控与所有者双向检查包括旧激活;损坏关联拒绝推进和终结,不依赖外键补救。此上限及每事务一个取消的吞吐仍需按P6实际负载验证,当前不作生产容量承诺。
CANCELLED仅表示本次流程停止已结清,不撤销先前成功的业务效果。停止回执中的CANCELLING也不表示外部执行已结束;必须通过后续实例、步骤与执行历史判断当前事实。
## 5. 升级与验证
[迁移000021](../internal/storage/mysql/migrations/000021_workflow_stop_intent.up.sql)新增两个带中文说明的停止字段及成对CHECK,增加任务所有者查询索引。35个实体、303个直接持久化字段声明,继续禁止数据库外键及级联删除。
历史显式取消保留cancel_requested_at;历史失败结清用原updated_at建立兼容停止边界。旧停止中的实例关闭门控并回填或提前根检查点;不更改control_revision、定义、输入、原截止或预算,终态及无停止条件的实例保持原样。升级顺序仍为停止旧写入节点 → 执行全部迁移 → 启动新版,不能让旧节点忽略新增停止字段继续写入。
[控制及结清回归](../internal/storage/mysql/workflow_controls_integration_test.go)覆盖控制版本、权限重报、开始竞争、失败/未知、审计回滚、信号与查询及超过32步骤接续;[真实v20升级](../internal/storage/mysql/workflow_stop_upgrade_integration_test.go)验证兼容回填;[实际Orbit进程回归](../internal/storage/mysql/workflow_runtime_process_integration_test.go)覆盖停止意图和结果在全停期间保存后由两个新进程接续。实际结果见[阶段报告](reports/phase-5-controls.md)。
公共实例/控制/信号/审计接口、独立SDK及基础可运行场景已接入,下一步补齐完整历史、来源与更多场景,再完成P6–P7生产故障、性能、运维和发布验收。当前测试不替代生产MySQL复制、故障切换、备份恢复或RPO/RTO验证。