# Weave 结果消费与自动推进 状态:TASK结果消费、顺序、分支、有限并行汇合、根检查点、TIMER/POLL及信号等待已接入Orbit后台。实例、控制、信号与恢复已经提供[公共API及独立SDK](api/workflows.md)。完整历史查询和生产验收继续按计划推进。 ## 1. 后台运行和事务边界 每个Orbit进程每秒调用一次`WorkflowRuntime.Tick`,一批最多100个候选、调用超时5秒。候选来自`weave_inbox`的PENDING到期索引和`weave_pending_advances`的到期索引,各候选独立事务。选择候选不授予执行权;同一应用繁忙时跳过,后续扫描重读数据库。 事务锁顺序是身份共享锁 → 应用额度排他锁 → 固定版本涉及的排序队列 → 实例 → 执行门控 → 激活/步骤及消费记录。不能先领取并持有Inbox锁,再倒过来锁应用或任务。运行器不向业务系统发请求,不需要Redis或额外消息队列;业务执行仍由Pulse授权Worker。 ```mermaid flowchart LR A[读取到期Inbox或根检查点] --> B[锁定并核验实例图] B --> C[读取冻结结果并校验来源] C --> D[更新步骤和计算有限决策] D --> E[创建后继工作或保存待续] E --> F[确认消费并写审计] F --> G[同一事务提交] ``` 每轮最多32个结构变更。达到预算时保留根步骤版本及ROOT检查点,由后续节点继续;后续计算仍使用固定版本、原输入和已保存结果。旧检查点只能基于当前持锁快照重新计算,不能覆盖更高步骤版本;超前版本或错误根身份拒绝执行。 ## 2. 结果、去重与审计 消费只使用内部Inbox的独立结果快照。校验结构版本、任务和队列、来源状态版本、原事件身份/类型/版本、激活所属实例和步骤、Pulse所有者及门控、尝试归属;POLL额外校验原轮次。任务当前结果不能替换历史快照。 | 情况 | 处理 | | --- | --- | | 已确认或已隔离的记录再次被扫描 | 不再次更新步骤、创建任务或写相同消费审计 | | 旧激活、已处理的旧轮次或低于已处理结果版本 | 保留来源,确认并记录稳定分类,不推动当前工作 | | 已结清步骤收到其他历史结果 | 保留处理历史,不重开步骤或改变已完成业务结果 | | 来源身份或结构矛盾 | QUARANTINED;未终结实例转NEEDS_REVIEW并关闭新执行门控 | | SQL/连接或事务异常 | 整笔回滚;仍保留PENDING。扫描器按原记录版本延后30秒,不能覆盖其他节点刚完成的确认 | | 正常TASK成功 | 验证固定输出契约,保存SUCCEEDED后有限推进 | | TASK确认取消 | 步骤保留CANCELLED和来源证据,不能改写为FAILED或启动正常后继 | | TASK失败、未知效果或不合契约的成功结果 | 停止依赖推进,保留原任务结果及稳定核查原因 | 每个成功提交的消费或实际根推进写系统审计,actor为`system:weave:`。审计使用独立操作身份,元信息保存来源Inbox/检查点ID、节点、实例版本及原因;同一个ROOT检查点可分批产生多次真实推进。每次历史变更取得新的实例revision,避免迟到证据与先前事件的唯一身份冲突。 审计失败会回滚消费确认、步骤状态和新任务。对外任务结果订阅继续使用原链路,内部消费不需要锁订阅或外部结果流。 ## 3. 满额、暂停和截止 后继创建使用SAVEPOINT隔离本轮结构变更。多后继中任何一个遇到队列或应用满额,全部本轮后继和对应额度预占回滚;已接受的来源结果及步骤完成仍能与ROOT待续记录一起提交。下一次尝试从当前图重新计算,不能留下部分激活、重复后继或多扣用量。持续满额仅移动检查时间,不逐秒制造相同业务审计。 暂停、关闭门控或停用应用/命名空间时,继续收集已经落库的结果,但不激活新步骤;若还有后继,将其保存为待续。重新允许推进后,从持久记录继续。测试通过直接设置控制状态验证该行为;内部暂停/继续控制已按[控制运行约定](15-workflow-controls.md)实现,公共HTTP/SDK尚未交付。 已过实例总截止时不创建后继,未能全部完成则进入核查。最后的有效任务结果在截止前已由Pulse接受,而消费发生较晚时,可以整理完整结果并完成实例。暂停或重启不延长截止。TIMER与POLL的时钟已接入;[SIGNAL及其超期/最终查询裁决](14-workflow-signals.md)已接入。 ## 4. POLL与失败策略的当前边界 已实现当前轮次的结果消费: - 查询请求成功但业务PENDING:保存WAITING、清除当前任务并按原事件时间加间隔保存`next_poll_at`,受原查询截止限制;不将PENDING输出交给后继。 - DONE等已声明成功值:按固定契约完成节点;如有最终信号等待,一并结清。 - 轮次耗尽、查询截止、未知/非法值或单轮请求失败:进入核查,不新建轮次绕过Pulse重试预算。 - 业务明确失败:按固定实例失败策略处理;REVIEW进入核查,FAIL_AFTER_SETTLED进入CANCELLING并关闭门控。 下一轮查询派发及到期扫描已实现,详见[时钟、预算与恢复](13-workflow-clock.md)。**FAIL_AFTER_SETTLED的剩余分支取消/收集/失败终态判定已接入[停止运行器](15-workflow-controls.md)。** CANCELLING保留未结清事实,只有全部已知结清后才能进入FAILED。信号抢先到达时保留当前查询,实际结果结清及竞争见[信号运行约定](14-workflow-signals.md)。 ## 5. 回归与后续工作 [存储回归](../internal/storage/mysql/workflow_runtime_integration_test.go)覆盖重复消费者、精确结果、并行汇合、部分后继满额回滚、审计回滚、暂停与停用接续、分批根恢复、来源隔离、旧激活/旧版本、失败/截止和POLL分类;[进程回归](../internal/storage/mysql/workflow_runtime_process_integration_test.go)强杀唯一Orbit进程,确认死亡后提交任务结果,再启动两个新进程接续。 进程回归由`make integration`构建二进制后显式执行。缺少一次性数据库或`ORBIT_TEST_SERVER_BINARY`时测试会跳过;跳过不构成进程恢复证据。验证记录见[本阶段报告](reports/phase-4-runtime.md)。 持久化信号等待及查询最终信号竞争已按[信号运行约定](14-workflow-signals.md)实现。内部控制及停止结清也已接入。实例公共API与独立SDK已接入,下一步包括完整历史、实例筛选分页及更多通用场景;流程任务来源已接入。P4整体及P5–P7继续按[完整计划](08-development-plan.md)执行。