feat: consume workflow results and resume durable advances

This commit is contained in:
2026-09-18 02:21:30 +08:00
parent 553a0bf522
commit f602a5ee05
15 changed files with 1458 additions and 15 deletions

View File

@@ -28,7 +28,7 @@
| P1 任务受理闭环 | 应用凭据与作用域权限、队列、幂等提交、查询、待执行取消、受理事件;SDK 客户端 | API/SDK 创建查询闭环;重复键与内容冲突、响应未确认重报、跨命名空间拒绝、参数边界 | 已完成并通过阶段回归(见 P1 报告;真实断路/提交 ACK 丢失注入留后续故障阶段) |
| P2 Worker 执行闭环 | WSS 接入、能力/容量、领取与开始、租约、续租、结果确认、排空与恢复;Worker SDK | 真 Worker 执行;失联/重连/重复确认/旧尝试拒绝;业务效果未知转核查;节点故障接管 | 已完成并通过阶段回归:服务端、自动 SDK、历史查询、完整 Schema 与真实进程强杀恢复;测试拓扑和剩余生产故障矩阵见 P2 验收报告 |
| P3 Pulse 完整能力 | 安全重试、延时、Cron/固定间隔、漏跑策略、计划版本、运行中取消、并发许可、配额/背压、可靠结果订阅、批量受理、独立任务核查/人工重试、查询筛选与事务Outbox接入 | 多实例领取/触发竞争、重试上限、取消竞争、队列隔离、积压恢复、事件重复交付 | 已完成平台功能阶段验收:[原范围逐项核对](reports/phase-3.md)、[本轮完整回归](reports/phase-3-delay-recovery.md)。补齐相对延迟、改参数关联示例和四种重试全停恢复场景;20个可运行示例全部通过。全平台生产门槛及SDK首版交付剩余项仍按P6–P7推进 |
| P4 Weave 主流程 | SDK 定义构建与发布校验、实例、顺序/分支/结构化并行汇合、信号/定时等待、版本绑定 | 重启接续、早到/重复信号、并行竞争、内部事件重放、发布版本兼容;端到端通用流程 | 定义格式/词法类型校验、不可变发布、独立SDK及六类节点定义例子已实现,已通过[子项验收](reports/phase-4-definitions.md);已补[有限决策器及内部结果交付](reports/phase-4-engine-core.md);[实例受理及首批事务](reports/phase-4-admission.md)已实现;事件消费推进、持久化等待运行器和实例公共API/SDK仍待实现 |
| P4 Weave 主流程 | SDK 定义构建与发布校验、实例、顺序/分支/结构化并行汇合、信号/定时等待、版本绑定 | 重启接续、早到/重复信号、并行竞争、内部事件重放、发布版本兼容;端到端通用流程 | 定义格式/词法类型校验、不可变发布、独立SDK及六类节点定义例子已实现,已通过[子项验收](reports/phase-4-definitions.md);已补[有限决策器及内部结果交付](reports/phase-4-engine-core.md);[实例受理及首批事务](reports/phase-4-admission.md)已实现;[结果消费和根接续](reports/phase-4-runtime.md)已接入后台,顺序/分支/并行及真实进程恢复已验证;持久化等待、完整控制和实例公共API/SDK继续开发 |
| P5 Weave 恢复与查询 | 有界查询、暂停继续、取消、人工核查恢复、控制门控与审计 | 轮次与尝试独立预算;暂停/开始/回执/超时竞争;恢复保留预算;未知结果不盲目重复 | 待开发 |
| P6 生产验证与运维 | 完整监控、凭据轮换、备份恢复、滚动升级、运行手册、可复现负载和故障工具 | 对照生产验收清单执行,报告环境/指标/遗留项;容量、RPO/RTO 按真实拓扑验证 | 待开发 |
| P7 首版交付核对 | SDK 兼容与发布准备、完整 API 手册、场景示例、全量回归及交付清单 | 新接入者按文档跑通全部示例;所有首版能力可追溯到实现与测试;报告实际生产边界 | 待开发 |

View File

@@ -1,6 +1,6 @@
# Weave 执行决策与内部结果交付
状态:P4 内部基础已实现。已接通Pulse结果到Weave持久化Inbox,并提供有限步骤决策器;[实例受理和首批存储适配](11-workflow-admission.md)已补齐。**Inbox消费推进、定时/信号运行器及实例公共API/SDK尚未实现**。不能把本页能力解释成流程已经可以端到端执行。
状态:P4 内部基础已实现。已接通Pulse结果到Weave持久化Inbox,并提供有限步骤决策器;[实例受理和首批存储适配](11-workflow-admission.md)已补齐。[Inbox消费推进及根检查点运行器](12-workflow-runtime.md)已接入;定时/信号运行器及实例公共API/SDK仍待实现。不能把本页能力解释成完整公开端到端流程已交付。
## 1. 为什么结果要独立持久化
@@ -23,7 +23,7 @@ flowchart LR
已实现的内部交付触发为`task.succeeded`、`task.failed`、`task.cancelled`、`task.needs_review`。任务暂时失败并等待自动重试,不新增流程激活或内部结果事件。相同完成回执重报不产生第二个事件;同一来源任务状态版本还有独立唯一约束。
发布后使用旧激活的在途结果仍保留原激活身份;生产者不自行判定是否推进当前激活。未来消费者须识别旧激活/旧轮次并留痕,不能将其用于当前工作。
发布后使用旧激活的在途结果仍保留原激活身份;生产者不自行判定是否推进当前激活。当前消费者识别旧激活/旧轮次并留痕,不能将其用于当前工作。
生产者在现有结果快照查询中一起读取所有者和关联标记;普通结果不增加一次单独网络查询。流程关联核验使用只读关联查询,不在已持有任务锁后再锁实例、步骤或对外订阅。内部Inbox写入发生在外部结果流行锁之前,保持既有锁顺序。
@@ -74,7 +74,7 @@ v16及以前的未处理记录缺少冻结来源,升级后统一标为QUARANTI
## 4. 后续存储适配必须满足的条件
以下是存储运行器的完整要求;第1项初始事务已实现并按[受理报告](reports/phase-4-admission.md)验证,其余消费/运行要求尚未完成,不能按纯单测宣称已完成:
以下保留存储运行器的完整要求。第1项已按[受理报告](reports/phase-4-admission.md)验证;第2–4项结果消费和根接续已接入[实际运行器](12-workflow-runtime.md),第5–7项的完整等待、控制、接口和SDK仍继续实现:
1. 启动时认证、固定不可变版本/输入和策略、校验全部队列、计算实例截止,并在同事务创建实例、门控、首批激活/任务及审计回执。相同身份返回原实例。
2. 消费者领取内部事件后核对命名空间、来源任务版本、激活/轮次及当前步骤版本;消费确认、步骤变化、后续任务或持久化待续记录同事务提交。

View File

@@ -1,6 +1,6 @@
# Weave 实例受理与首批工作
状态:内部Go服务与MySQL存储适配已实现实例Start/Get/Steps、固定版本、首批决策落库和可靠结果交付。**尚未开放实例HTTP路由、启动SDK或命令行入口;后台Inbox消费、待续扫描和等待运行器尚未接通。** Weave相关公开SDK目前仅支持定义发布。不能将首批任务可执行解释成整个流程已能自动完成。
状态:内部Go服务与MySQL存储适配已实现实例Start/Get/Steps、固定版本、首批决策落库和可靠结果交付。[后台Inbox消费和根待续扫描](12-workflow-runtime.md)已接通。**尚未开放实例HTTP路由、启动SDK或命令行入口;等待运行器、后续轮询和完整控制仍继续开发。** Weave相关公开SDK目前仅支持定义发布。TASK及组合节点已可自动推进,不能将此解释成全部等待/控制能力已实现。
## 1. 受理事务
@@ -23,7 +23,7 @@
| --- | --- |
| TASK | 当前激活、精确输入、所属Pulse任务、流程门控及`workflow_activation`所有者 |
| BRANCH | 首次选择的case索引;未选中节点分批SKIPPED,不创建业务激活 |
| PARALLEL | 父激活、独立分支初始工作;完成汇合仍需要后续消费推进 |
| PARALLEL | 父激活、独立分支初始工作;后续结果消费运行器负责完成汇合 |
| SIGNAL | WAITING激活、信号名称/内容版本/精确业务关联、固定截止;不分配Worker |
| TIMER | WAITING激活和数据库时间计算的等待截止;不生成业务任务 |
| POLL | 固定输入、查询状态、首轮记录和唯一当前任务;used_rounds=1;可选最终信号等待与查询截止一致 |
@@ -49,14 +49,14 @@ Get返回当前实例视图;Start重报返回受理时冻结的原始视图,
| 活跃实例 | 每个namespace最多10000个RUNNING/WAITING/CANCELLING/NEEDS_REVIEW实例;终态不计入;满额仍可恢复原受理回执 |
| 信号关联 | 新受理最多512字节;数据库兼容旧191字符最长764字节,升级不截断历史 |
| 截止 | 数据库时间生成;任务、查询与等待均不超过实例总截止 |
| 自动运行 | 本阶段尚未实现Inbox消费、待续扫描、信号消费、定时到期处理或后续轮询 |
| 自动运行 | Inbox消费和根待续扫描已接入;信号消费、定时到期处理及后续轮询仍待实现 |
迁移000018为Wait增加signal_name和payload_version两个带中文注释的可空字段;NULL仅表示TIMER或尚未核实的历史元数据,未来消费者不得把历史NULL自动解释为有效的新信号等待。correlation_key转为精确字节存储;实例business_key改为utf8mb4_0900_bin。35个实体、含公共Record的295个直接持久化字段声明,全部有中文注释,继续保持零外键。
## 5. 下一步接入
1. 锁定实例、核验来源快照/当前激活,消费确认与后续步骤/任务/待续记录同事务;处理重复、迟到、旧轮次和未知结果。
2. 实现有界待续扫描与数据库时间驱动的等待,恢复时保留原截止和次数;开始扫描前补齐暂停/截止/凭据所属应用停用的判定。
1. 结果消费与根待续运行器已按[运行器报告](reports/phase-4-runtime.md)验证;继续补齐数据库时间驱动的信号/定时等待。
2. 已有扫描核验暂停、截止与所属应用停用;继续后续轮次派发、回执竞争及失败分支结清,恢复保留原截止和次数。
3. 接通实例公共HTTP、独立SDK、来源查询和可运行端到端场景,同时实施真实节点退出与接管回归。
本阶段验证见[实例受理回归记录](reports/phase-4-admission.md)。纯受理测试不是流程运行验收,P4–P7仍按[完整计划](08-development-plan.md)推进。

View File

@@ -0,0 +1,67 @@
# Weave 结果消费与自动推进
状态:内部实例的TASK结果消费、顺序、分支、有限并行汇合和根检查点接续已接入Orbit后台运行器。实例公共HTTP/SDK仍未开放。信号/定时等待、下一轮查询、失败后的分支取消结清及人工恢复仍继续开发,不能将本阶段等同于完整Weave交付。
## 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:<node_id>`。审计使用独立操作身份,元信息保存来源Inbox/检查点ID、节点、实例版本及原因;同一个ROOT检查点可分批产生多次真实推进。每次历史变更取得新的实例revision,避免迟到证据与先前事件的唯一身份冲突。
审计失败会回滚消费确认、步骤状态和新任务。对外任务结果订阅继续使用原链路,内部消费不需要锁订阅或外部结果流。
## 3. 满额、暂停和截止
后继创建使用SAVEPOINT隔离本轮结构变更。多后继中任何一个遇到队列或应用满额,全部本轮后继和对应额度预占回滚;已接受的来源结果及步骤完成仍能与ROOT待续记录一起提交。下一次尝试从当前图重新计算,不能留下部分激活、重复后继或多扣用量。持续满额仅移动检查时间,不逐秒制造相同业务审计。
暂停、关闭门控或停用应用/命名空间时,继续收集已经落库的结果,但不激活新步骤;若还有后继,将其保存为待续。重新允许推进后,从持久记录继续。测试通过直接设置控制状态验证该行为;暂停/继续公共接口尚未交付。
已过实例总截止时不创建后继,未能全部完成则进入核查。最后的有效任务结果在截止前已由Pulse接受,而消费发生较晚时,可以整理完整结果并完成实例。暂停或重启不延长截止。纯等待实例到期及信号裁决仍需后续等待扫描器。
## 4. POLL与失败策略的当前边界
已实现当前轮次的结果消费:
- 查询请求成功但业务PENDING:保存WAITING、清除当前任务并按原事件时间加间隔保存`next_poll_at`,受原查询截止限制;不将PENDING输出交给后继。
- DONE等已声明成功值:按固定契约完成节点;如有最终信号等待,一并结清。
- 轮次耗尽、查询截止、未知/非法值或单轮请求失败:进入核查,不新建轮次绕过Pulse重试预算。
- 业务明确失败:按固定实例失败策略处理;REVIEW进入核查,FAIL_AFTER_SETTLED进入CANCELLING并关闭门控。
**尚未实现下一轮查询派发及其到期索引扫描,也未实现FAIL_AFTER_SETTLED的剩余分支取消/收集/失败终态判定。** CANCELLING保留未结清事实,不提前宣称FAILED。信号抢先完成时与当前在途查询的结清竞争,也属于后续必须实现的功能。
## 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)。
下一步仍包括持久化定时/信号等待、轮询后续轮次、完整控制与人工恢复、实例/来源公共API、独立SDK和通用端到端场景。P4整体及P5–P7继续按[完整计划](08-development-plan.md)执行。

View File

@@ -17,6 +17,10 @@
| [06 Weave 流程设计](06-workflow-spec.md) | 已确认的首版功能、研发定义发布、持久化等待、有界查询、暂停恢复与模块协作 |
| [07 数据模型](07-data-model.md) | 当前 Go 实体、数据库约束、存储约定与实现边界 |
| [08 持续开发计划](08-development-plan.md) | 开发、测试回归、阶段验收与最终交付目标 |
| [09 可靠结果订阅](09-result-subscription-core.md) | 提交水位、冻结结果与可靠交付 |
| [10 Weave决策与交付](10-workflow-engine-core.md) | 有限步骤决策和内部结果Inbox |
| [11 Weave实例受理](11-workflow-admission.md) | 固定版本、初始图和首批任务事务 |
| [12 Weave结果消费与推进](12-workflow-runtime.md) | 后台消费、根接续、事务与进程恢复,及尚未完成的等待/控制边界 |
| [接口手册](api/README.md) | 实际接口状态、调用说明与后续接口规划 |
| [SDK 与场景](sdk/README.md) | 可运行示例、接入方法及分阶段 SDK 交付 |

View File

@@ -0,0 +1,45 @@
# P4 结果消费与自动推进回归
日期:2026-09-18。范围为内部运行器,不是完整Weave或生产高可用验收。
## 已实现
- Orbit后台按数据库到期索引消费内部结果和根检查点;同一事务校验固定实例图、接受结果、更新步骤、创建后继或保存待续,并写确认、事件和审计。
- 顺序、分支、有限并行汇合及32步预算接续;重复消费者不重复创建后继。
- 满额SAVEPOINT回滚本轮后继,保留已确认结果;暂停/停用收集在途结果并保留检查点;失败或超期关闭新执行门控。
- 来源/激活/任务版本校验,非法来源隔离,旧激活或旧结果留痕;数据库故障不被误认成业务失败。
- POLL当前轮次的成功/等待/失败/核查分类,独立保留轮次与尝试预算、绝对截止和下一查询时间。
- 系统审计保存节点、来源记录与实例版本;真实进程强杀、全停时保存结果和双节点接管。
实现说明及明确边界见[运行器文档](../12-workflow-runtime.md)。本轮未增加实体、持久化字段、迁移或外键。
## 环境与执行记录
本机darwin/arm64,Go 1.27.1,独立Docker MySQL 8.4.10;隔离一次性数据库。未使用业务数据库或远端生产环境。
| 检查 | 结果 |
| --- | --- |
| `make fmt test vet build` | 已通过;服务端、独立SDK及两个业务示例module |
| 运行器真实MySQL定向回归 | 14个一级场景,含任务失败/未知/取消/非法输出4种分类及5个POLL分类;最终修订连续3轮通过,20.018秒 |
| 真实Orbit进程故障 | 已通过:确认唯一控制进程SIGKILL退出后保存结果,两个新进程只生成一个后继,最终3个任务、3条消费确认及3条推进审计 |
| 全量`make integration`等价脚本 | 已通过,退出码0;全存储132.893秒、流程进程8.506秒、Worker SDK 91.172秒、SDK进程故障93.679秒;19个SDK示例及2个独立业务示例全部通过 |
定向命令为`go test -race -count=3 -run '^TestIntegrationWorkflowRuntime$' -v ./internal/storage/mysql`,依赖`ORBIT_TEST_MYSQL_DSN`指向隔离测试库。进程用例额外需要构建后的`ORBIT_TEST_SERVER_BINARY`;全量入口[脚本](../../scripts/test-mysql.sh)负责创建隔离库、构建并执行该用例。
文档复核834个本地链接与53个JSON代码块,错误0;差异空白检查通过。
数据库复核MySQL 8.4.10、外键0、缺少COMMENT的业务列0。完整迁移升级回归与现有索引/数据保留检查通过。
开发中真实回归发现并修复了:未完成步骤NULL输出的SQL读取不兼容、分批复用检查点引发审计操作身份冲突;随后增加迟到结果历史版本回归,确保新确认不与先前实例事件冲突。后继额度中途失败和审计失败分别注入验证了事务回滚。
全量回归启动后,代码审阅补充了TASK确认取消保留CANCELLED状态,并新增对应真实Worker回归。最终修订另跑全部运行器场景三轮(20.018秒)、真实进程故障(9.183秒)及基础检查;全量记录与最后定向记录分别保留,不能把较早的全量结果声称为包含后续修改。
## 尚未完成的原定范围
1. SIGNAL/TIMER等待消费及到期扫描;早到、重复、超时和回执竞态。
2. POLL下一轮派发、完整定时扫描、信号与在途查询结清;已有next_poll_at不代表下一轮已自动运行。
3. FAIL_AFTER_SETTLED分支取消和失败终态收敛、暂停/继续/取消公共管理API、带证据人工恢复。
4. 实例/步骤/来源公共HTTP和独立SDK、全节点可运行接入例子。
5. 全量监控、负载与故障矩阵、MySQL高可用拓扑和备份恢复、P6–P7交付审计。
本地进程回归使用内部Start和Pulse执行存储驱动业务结果;这验证真实控制进程接管,不能替代公共HTTP/SDK端到端验收,也不证明生产数据库RPO/RTO或容量。