feat: recover poll activations within original round budgets
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Weave 流程编排功能与设计
|
||||
|
||||
> 版本 0.7 · 2026-09-18。首版功能范围已确认。定义结构、发布校验与不可变版本已实现,见[定义格式](api/workflow-definition-format.md)和[发布API](api/workflow-definitions.md);[实例受理](11-workflow-admission.md)、[结果消费与根推进](12-workflow-runtime.md)、[TIMER与POLL时钟](13-workflow-clock.md)已接入。[信号等待及最终查询竞争](14-workflow-signals.md)已接入内部运行器;[暂停/继续/取消与停止结清](15-workflow-controls.md)已实现内部链路;[人工核查与TASK恢复](16-workflow-recovery.md)已接入内部服务;POLL/等待恢复及实例公共API/SDK仍待P4–P5实现验收。
|
||||
> 版本 0.8 · 2026-09-18。首版功能范围已确认。定义结构、发布校验与不可变版本已实现,见[定义格式](api/workflow-definition-format.md)和[发布API](api/workflow-definitions.md);[实例受理](11-workflow-admission.md)、[结果消费与根推进](12-workflow-runtime.md)、[TIMER与POLL时钟](13-workflow-clock.md)已接入。[信号等待及最终查询竞争](14-workflow-signals.md)已接入内部运行器;[暂停/继续/取消与停止结清](15-workflow-controls.md)已实现内部链路;[人工核查与TASK恢复](16-workflow-recovery.md)已接入内部服务;[POLL跨激活恢复](17-workflow-poll-recovery.md)已接入;独立SIGNAL/TIMER等待重建及实例公共API/SDK仍待P4–P5实现验收。
|
||||
|
||||
## 1. 职责与边界
|
||||
|
||||
@@ -136,7 +136,7 @@ Weave 不执行特定业务逻辑,也不把整段业务代码放入平台进
|
||||
|
||||
查询任务自身成功表示取得了一份有效结果。其中“处理中”使 Weave 保存等待与下一次唤醒;最终业务结果则结束查询节点,按定义推进或进入失败处理。单轮请求重试耗尽应转核查,不能通过新建一轮绕过已耗尽的重试预算。
|
||||
|
||||
每轮只创建一个查询任务,以命名空间、实例、步骤激活和轮次形成稳定去重身份。轮次之间释放业务 Worker 槽位,等待依赖数据库记录与平台到期索引扫描;SDK 不在处理器中长期 sleep 或维护内存轮询循环。
|
||||
每个步骤激活的每轮只创建一个查询任务,以命名空间、实例、步骤激活和轮次形成稳定去重身份。人工恢复同一业务轮时创建新激活、保留原轮编号并扣除历史尝试,见[查询恢复](17-workflow-poll-recovery.md)。轮次之间释放业务 Worker 槽位,等待依赖数据库记录与平台到期索引扫描;SDK 不在处理器中长期 sleep 或维护内存轮询循环。
|
||||
|
||||
2026-09-18实现决策:TIMER/POLL直接复用`weave_pending_advances`检查点和后台扫描,替代早期草案的Pulse内部唤醒任务。唤醒只改变流程持久状态,不调用业务处理器,因此无需额外占用任务/尝试/许可记录;业务查询仍由Pulse执行。当前schema使用固定间隔,不提供业务轮次抖动或变长退避,具体冻结和升级行为见[运行约定](13-workflow-clock.md)。
|
||||
|
||||
@@ -174,7 +174,7 @@ Weave 不执行特定业务逻辑,也不把整段业务代码放入平台进
|
||||
3. 在一个事务内记录管理操作,创建新的步骤激活及关联 Pulse 任务,并固定关联关系。
|
||||
4. 保留旧激活与旧任务结果,沿用恰当的业务幂等身份。
|
||||
|
||||
执行核查、步骤结论、解除核查及TASK新激活已按[人工恢复约定](16-workflow-recovery.md)实现内部服务,原预算和绝对截止不重置;POLL跨激活及等待恢复仍需补齐,公共API另行交付。普通任务人工重试入口应拒绝绕过流程管理的关联任务请求。已经确认成功的步骤不能通过“重试流程”随意再执行一次。
|
||||
执行核查、步骤结论、解除核查及TASK新激活已按[人工恢复约定](16-workflow-recovery.md)实现内部服务,原预算和绝对截止不重置;[POLL跨激活恢复](17-workflow-poll-recovery.md)已接入,独立SIGNAL/TIMER等待重建仍需补齐,公共API另行交付。普通任务人工重试入口应拒绝绕过流程管理的关联任务请求。已经确认成功的步骤不能通过“重试流程”随意再执行一次。
|
||||
|
||||
取消和补偿是不同业务操作。若未来增加补偿,补偿本身也必须是有权限、可审计、可重试或可核查的业务步骤;不能宣称撤销流程就能撤回已经生效的外部业务操作。
|
||||
|
||||
|
||||
@@ -207,8 +207,13 @@ Signal新增payload_version、target_activation_sequence、evidence_ref、dispos
|
||||
|
||||
## 停止意图增量(000021)
|
||||
|
||||
Instance新增StopKind和StopRequestedAt,冻结首次用户取消或失败结清目标;CancelRequestedAt仍只表示用户显式取消。成对CHECK防止半条意图,任务所有者索引支持双向归属核验。当前35个实体、303个直接持久化字段声明,均有中文注释。历史停止实例关闭门控并恢复根接续,不改变原截止、预算、控制版本或终态数据;保持零外键,详见[控制约定](15-workflow-controls.md)。
|
||||
Instance新增StopKind和StopRequestedAt,冻结首次用户取消或失败结清目标;CancelRequestedAt仍只表示用户显式取消。成对CHECK防止半条意图,任务所有者索引支持双向归属核验。截至000021为35个实体、303个直接持久化字段声明,均有中文注释。历史停止实例关闭门控并恢复根接续,不改变原截止、预算、控制版本或终态数据;保持零外键,详见[控制约定](15-workflow-controls.md)。
|
||||
|
||||
## 流程人工核查与TASK新激活
|
||||
|
||||
复用现有激活sequence、任务retry_of、审计和幂等回执,不增加表、字段或外键。TASK人工重试以新激活保留旧执行,原尝试预算跨激活扣除,原绝对截止不改变;执行核查和步骤逻辑结论分别保存。35个实体、303个中文注释字段。当前内部支持范围与POLL/等待恢复剩余项见[核查约定](16-workflow-recovery.md)。
|
||||
复用现有激活sequence、任务retry_of、审计和幂等回执,不增加表、字段或外键。TASK人工重试以新激活保留旧执行,原尝试预算跨激活扣除,原绝对截止不改变;执行核查和步骤逻辑结论分别保存。35个实体、303个中文注释字段。当前内部支持范围与独立SIGNAL/TIMER等待重建剩余项见[核查约定](16-workflow-recovery.md)。
|
||||
|
||||
|
||||
### 000022:跨激活保留查询轮次与尝试
|
||||
|
||||
PollState新增FirstRound和FirstRoundAttemptsUsed,记录当前激活的首个业务轮及该轮在旧激活已消耗的尝试。UsedRounds继续使用首次激活起的业务轮编号;原单轮尝试和查询/请求绝对截止均不重置。新业务轮恢复原单轮策略,人工恢复同轮只分配剩余尝试。当前35个实体、305个直接持久化字段声明,Go/SQL均有中文注释,无外键。v21升级保留旧数据、时间和预算,详情见[查询恢复](17-workflow-poll-recovery.md)。
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
| 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)已实现;[结果消费和根接续](reports/phase-4-runtime.md)已接入后台,顺序/分支/并行及真实进程恢复已验证;[TIMER与后续POLL轮次](13-workflow-clock.md)已接入;[信号消费和最终查询竞争](14-workflow-signals.md)已接入内部运行器;[内部控制与停止结清](15-workflow-controls.md)已接入;[内部核查与TASK新激活](16-workflow-recovery.md)已接入;POLL/等待恢复和实例公共API/SDK继续开发 |
|
||||
| P5 Weave 恢复与查询 | 有界查询、暂停继续、取消、人工核查恢复、控制门控与审计 | 轮次与尝试独立预算;暂停/开始/回执/超时竞争;恢复保留预算;未知结果不盲目重复 | 有界查询轮次/尝试独立预算及原截止恢复已接入内部运行器;最终信号竞争及在途查询结清已接入;内部暂停/继续/取消与失败结清已接入;执行核查、步骤结论、解除核查及TASK新激活已接入;POLL/等待恢复及公共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)已接入后台,顺序/分支/并行及真实进程恢复已验证;[TIMER与后续POLL轮次](13-workflow-clock.md)已接入;[信号消费和最终查询竞争](14-workflow-signals.md)已接入内部运行器;[内部控制与停止结清](15-workflow-controls.md)已接入;[内部核查与TASK新激活](16-workflow-recovery.md)已接入;独立SIGNAL/TIMER等待重建和实例公共API/SDK继续开发 |
|
||||
| P5 Weave 恢复与查询 | 有界查询、暂停继续、取消、人工核查恢复、控制门控与审计 | 轮次与尝试独立预算;暂停/开始/回执/超时竞争;恢复保留预算;未知结果不盲目重复 | 有界查询轮次/尝试独立预算及原截止恢复已接入内部运行器;最终信号竞争及在途查询结清已接入;内部暂停/继续/取消与失败结清已接入;执行核查、步骤结论、解除核查及TASK新激活已接入;[POLL跨激活恢复](17-workflow-poll-recovery.md)已接入;独立SIGNAL/TIMER等待重建及公共API/SDK继续开发 |
|
||||
| P6 生产验证与运维 | 完整监控、凭据轮换、备份恢复、滚动升级、运行手册、可复现负载和故障工具 | 对照生产验收清单执行,报告环境/指标/遗留项;容量、RPO/RTO 按真实拓扑验证 | 待开发 |
|
||||
| P7 首版交付核对 | SDK 兼容与发布准备、完整 API 手册、场景示例、全量回归及交付清单 | 新接入者按文档跑通全部示例;所有首版能力可追溯到实现与测试;报告实际生产边界 | 待开发 |
|
||||
|
||||
@@ -41,8 +41,8 @@ P4/P5定时等待与后续查询轮次的实现及回归记录见[时钟报告](
|
||||
|
||||
1. 已实现FAIL_AFTER_SETTLED与显式取消的内部分支结清,见[控制报告](reports/phase-5-controls.md):持久取消意图、复用Pulse取消、收集已发出查询/任务结果、等待全部已激活工作结清后才进入失败或取消终态。效果未知仍保留核查。
|
||||
2. 已实现实例暂停/继续/取消内部操作,以control_revision、操作幂等身份、明确原因及审计保护控制决定;暂停不延长原截止,继续不覆盖核查或取消状态。
|
||||
3. 已实现内部执行核查、步骤结论、解除核查及TASK新激活和旧激活隔离,见[核查报告](reports/phase-5-recovery.md)。继续POLL跨激活及等待恢复,保留原预算、轮次、结果和证据,不能通过换激活/新键绕过未知效果或执行上限。
|
||||
4. 同步开放实例/步骤/信号/来源/审计HTTP、独立SDK和端到端场景,覆盖原键恢复、权限、版本冲突、竞争与进程全停;公共能力逐项记录实际验收结果。
|
||||
3. 已实现内部执行核查、步骤结论、解除核查及TASK新激活和旧激活隔离,见[核查报告](reports/phase-5-recovery.md)。POLL跨激活恢复已实现(见[查询恢复](17-workflow-poll-recovery.md));继续核查后已确认PENDING的有界等待接续及独立SIGNAL/TIMER等待重建,保留原预算、轮次、结果和证据,不能通过换激活/新键绕过未知效果或执行上限。
|
||||
4. 同步开放实例/步骤/信号/来源/审计HTTP、独立SDK和端到端场景,覆盖原键恢复、权限、版本冲突、竞争与进程全停;公共步骤/激活查询须返回目标激活代次,调用方据此发送恢复后的信号,不能要求调用方自行猜测sequence。公共能力逐项记录实际验收结果。
|
||||
5. 转入P6/P7的生产故障、容量、运维、发布与全部文档核对。内部存储阶段通过不会提前勾选公共接口或生产验收。
|
||||
|
||||
### P3 功能范围核对
|
||||
@@ -119,6 +119,8 @@ P4/P5定时等待与后续查询轮次的实现及回归记录见[时钟报告](
|
||||
|
||||
## 7. 文档入口
|
||||
|
||||
- [有界查询恢复](17-workflow-poll-recovery.md)
|
||||
- [POLL恢复验证记录](reports/phase-5-poll-recovery.md)
|
||||
- [数据模型](07-data-model.md)
|
||||
- [可靠结果订阅核心](09-result-subscription-core.md)
|
||||
- [P3 订阅核心回归](reports/phase-3-result-subscription-core.md)
|
||||
|
||||
@@ -74,7 +74,7 @@ v16及以前的未处理记录缺少冻结来源,升级后统一标为QUARANTI
|
||||
|
||||
## 4. 后续存储适配必须满足的条件
|
||||
|
||||
以下保留存储运行器的完整要求。第1项已按[受理报告](reports/phase-4-admission.md)验证;第2–4项结果消费和根接续已接入[实际运行器](12-workflow-runtime.md),第5项的TIMER/POLL已接入[时钟运行器](13-workflow-clock.md),第5项的信号等待已接入[信号运行器](14-workflow-signals.md),内部控制与结清已接入[控制运行器](15-workflow-controls.md),[核查与TASK新激活](16-workflow-recovery.md)已接入;POLL/等待恢复、接口和SDK仍继续实现:
|
||||
以下保留存储运行器的完整要求。第1项已按[受理报告](reports/phase-4-admission.md)验证;第2–4项结果消费和根接续已接入[实际运行器](12-workflow-runtime.md),第5项的TIMER/POLL已接入[时钟运行器](13-workflow-clock.md),第5项的信号等待已接入[信号运行器](14-workflow-signals.md),内部控制与结清已接入[控制运行器](15-workflow-controls.md),[核查与TASK新激活](16-workflow-recovery.md)已接入;独立SIGNAL/TIMER等待重建、接口和SDK仍继续实现:
|
||||
|
||||
1. 启动时认证、固定不可变版本/输入和策略、校验全部队列、计算实例截止,并在同事务创建实例、门控、首批激活/任务及审计回执。相同身份返回原实例。
|
||||
2. 消费者领取内部事件后核对命名空间、来源任务版本、激活/轮次及当前步骤版本;消费确认、步骤变化、后续任务或持久化待续记录同事务提交。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Weave 实例受理与首批工作
|
||||
|
||||
状态:内部Go服务与MySQL存储适配已实现实例Start/Get/Steps、固定版本、首批决策落库和可靠结果交付。[后台Inbox消费和根待续扫描](12-workflow-runtime.md)已接通。**尚未开放实例HTTP路由、启动SDK或命令行入口;[内部控制和结清](15-workflow-controls.md)已接入,[内部核查及TASK恢复](16-workflow-recovery.md)已接入,POLL/等待恢复继续开发;[信号运行器](14-workflow-signals.md)已接入。** Weave相关公开SDK目前仅支持定义发布。[TIMER和后续POLL轮次](13-workflow-clock.md)已接入,TASK及组合节点已可自动推进,不能将此解释成全部等待/控制能力已实现。
|
||||
状态:内部Go服务与MySQL存储适配已实现实例Start/Get/Steps、固定版本、首批决策落库和可靠结果交付。[后台Inbox消费和根待续扫描](12-workflow-runtime.md)已接通。**尚未开放实例HTTP路由、启动SDK或命令行入口;[内部控制和结清](15-workflow-controls.md)已接入,[内部核查及TASK恢复](16-workflow-recovery.md)已接入,独立SIGNAL/TIMER等待重建继续开发;[信号运行器](14-workflow-signals.md)已接入。** Weave相关公开SDK目前仅支持定义发布。[TIMER和后续POLL轮次](13-workflow-clock.md)已接入,TASK及组合节点已可自动推进,不能将此解释成全部等待/控制能力已实现。
|
||||
|
||||
## 1. 受理事务
|
||||
|
||||
@@ -49,7 +49,7 @@ Get返回当前实例视图;Start重报返回受理时冻结的原始视图,
|
||||
| 活跃实例 | 每个namespace最多10000个RUNNING/WAITING/CANCELLING/NEEDS_REVIEW实例;终态不计入;满额仍可恢复原受理回执 |
|
||||
| 信号关联 | 新受理最多512字节;数据库兼容旧191字符最长764字节,升级不截断历史 |
|
||||
| 截止 | 数据库时间生成;任务、查询与等待均不超过实例总截止 |
|
||||
| 自动运行 | Inbox消费、根待续、TIMER到期及后续POLL轮次已接入;SIGNAL与最终查询竞争已接入,内部控制与结清已接入,内部核查及TASK恢复已接入,POLL/等待恢复仍待实现 |
|
||||
| 自动运行 | Inbox消费、根待续、TIMER到期及后续POLL轮次已接入;SIGNAL与最终查询竞争已接入,内部控制与结清已接入,内部核查及TASK恢复已接入,独立SIGNAL/TIMER等待重建仍待实现 |
|
||||
|
||||
迁移000018为Wait增加signal_name和payload_version两个带中文注释的可空字段;NULL仅表示TIMER或尚未核实的历史元数据,未来消费者不得把历史NULL自动解释为有效的新信号等待。correlation_key转为精确字节存储;实例business_key改为utf8mb4_0900_bin。该迁移时为35个实体、含公共Record的295个直接持久化字段声明,全部有中文注释,继续保持零外键。
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Weave 结果消费与自动推进
|
||||
|
||||
状态:内部实例的TASK结果消费、顺序、分支、有限并行汇合和根检查点接续已接入Orbit后台运行器。[定时等待和后续查询轮次](13-workflow-clock.md)也已接入。[信号等待与最终查询竞争](14-workflow-signals.md)已接入。实例公共HTTP/SDK仍未开放,[失败后的分支取消结清与内部控制](15-workflow-controls.md)已接入,[内部核查及TASK恢复](16-workflow-recovery.md)已接入,POLL/等待恢复继续开发,不能将本阶段等同于完整Weave交付。
|
||||
状态:内部实例的TASK结果消费、顺序、分支、有限并行汇合和根检查点接续已接入Orbit后台运行器。[定时等待和后续查询轮次](13-workflow-clock.md)也已接入。[信号等待与最终查询竞争](14-workflow-signals.md)已接入。实例公共HTTP/SDK仍未开放,[失败后的分支取消结清与内部控制](15-workflow-controls.md)已接入,[内部核查及TASK恢复](16-workflow-recovery.md)已接入,独立SIGNAL/TIMER等待重建继续开发,不能将本阶段等同于完整Weave交付。
|
||||
|
||||
## 1. 后台运行和事务边界
|
||||
|
||||
@@ -64,4 +64,4 @@ flowchart LR
|
||||
|
||||
进程回归由`make integration`构建二进制后显式执行。缺少一次性数据库或`ORBIT_TEST_SERVER_BINARY`时测试会跳过;跳过不构成进程恢复证据。验证记录见[本阶段报告](reports/phase-4-runtime.md)。
|
||||
|
||||
持久化信号等待及查询最终信号竞争已按[信号运行约定](14-workflow-signals.md)实现。内部控制及停止结清也已接入。下一步仍包括POLL/等待恢复、实例/来源公共API、独立SDK和通用端到端场景。P4整体及P5–P7继续按[完整计划](08-development-plan.md)执行。
|
||||
持久化信号等待及查询最终信号竞争已按[信号运行约定](14-workflow-signals.md)实现。内部控制及停止结清也已接入。下一步仍包括独立SIGNAL/TIMER等待重建、实例/来源公共API、独立SDK和通用端到端场景。P4整体及P5–P7继续按[完整计划](08-development-plan.md)执行。
|
||||
|
||||
@@ -61,3 +61,5 @@ TIMER由待续表直接唤醒,不创建Pulse业务任务,也不占Worker执
|
||||
[存储回归](../internal/storage/mysql/workflow_clock_integration_test.go)覆盖到期、竞争、预算、暂停/满额、回滚、归属损坏与未知结果;[v18升级回归](../internal/storage/mysql/workflow_clock_upgrade_integration_test.go)验证回填及原预算保留;[真实进程回归](../internal/storage/mysql/workflow_runtime_process_integration_test.go)覆盖全部控制进程退出后的定时和查询接续。执行记录见[阶段报告](reports/phase-4-clock.md)。
|
||||
|
||||
SIGNAL早到/重复/超期处理及最终查询竞争已接入;内部失败分支结清和控制已接入;下一阶段继续人工恢复、公共控制及实例SDK,完整范围见[持续计划](08-development-plan.md)。
|
||||
|
||||
人工恢复跨激活后,查询原截止、连续业务轮编号和同轮请求预算仍保留;首轮已解析输入始终从首次激活读取。具体规则见[有界查询恢复](17-workflow-poll-recovery.md)。
|
||||
|
||||
@@ -65,4 +65,4 @@
|
||||
|
||||
[受理回归](../internal/storage/mysql/workflow_signals_integration_test.go)、[消费回归](../internal/storage/mysql/workflow_signal_runtime_integration_test.go)、[真实v19升级](../internal/storage/mysql/workflow_signal_upgrade_integration_test.go)和[实际进程恢复](../internal/storage/mysql/workflow_runtime_process_integration_test.go)对应受理/并发/故障/升级边界,实际运行结果记录在[阶段报告](reports/phase-4-signals.md)。
|
||||
|
||||
内部失败分支取消结清、实例暂停/继续/取消已接入。下一步完成人工核查恢复,再交付实例与信号HTTP、独立SDK及完整场景。当前内部存储测试不替代尚未开放的公共接口验收,也不替代生产MySQL切换与容量测试。
|
||||
内部失败分支取消结清、实例暂停/继续/取消已接入。人工核查及[POLL新激活的最终信号换代](17-workflow-poll-recovery.md)已接入;下一步完成独立等待重建,再交付实例与信号HTTP、独立SDK及完整场景。当前内部存储测试不替代尚未开放的公共接口验收,也不替代生产MySQL切换与容量测试。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Weave 控制与停止结清
|
||||
|
||||
状态:内部Go暂停、继续、取消服务及后台失败/取消结清运行器已接入。**公共实例/控制HTTP与独立SDK尚未开放,[内部核查及TASK新激活](16-workflow-recovery.md)已接入,POLL/等待恢复仍在后续交付范围**。本文说明已实现的持久化规则,不把内部存储回归当作全部Weave或生产验收。
|
||||
状态:内部Go暂停、继续、取消服务及后台失败/取消结清运行器已接入。**公共实例/控制HTTP与独立SDK尚未开放,[内部核查及TASK新激活](16-workflow-recovery.md)已接入,独立SIGNAL/TIMER等待重建仍在后续交付范围**。本文说明已实现的持久化规则,不把内部存储回归当作全部Weave或生产验收。
|
||||
|
||||
## 1. 控制操作
|
||||
|
||||
@@ -60,4 +60,4 @@ CANCELLED仅表示本次流程停止已结清,不撤销先前成功的业务
|
||||
|
||||
[控制及结清回归](../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)。
|
||||
|
||||
下一步仍需完成POLL/等待恢复、公共实例/控制/信号/审计接口、独立SDK及可运行场景,再完成P6–P7生产故障、性能、运维和发布验收。当前测试不替代生产MySQL复制、故障切换、备份恢复或RPO/RTO验证。
|
||||
下一步仍需完成独立SIGNAL/TIMER等待重建、公共实例/控制/信号/审计接口、独立SDK及可运行场景,再完成P6–P7生产故障、性能、运维和发布验收。当前测试不替代生产MySQL复制、故障切换、备份恢复或RPO/RTO验证。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Weave 人工核查与接续
|
||||
|
||||
状态:内部Go服务已提供执行核查、步骤结论确认、解除核查,以及TASK新激活重试。公共HTTP、独立SDK和通用接入示例尚未交付;**POLL新激活恢复尚未实现,不能把已有逻辑结果核查当作查询重试已经完成**。完整交付继续按[开发计划](08-development-plan.md)推进。
|
||||
状态:内部Go服务已提供执行核查、步骤结论确认、解除核查,以及TASK/POLL新激活重试。POLL跨激活预算与附属信号换代见[查询恢复](17-workflow-poll-recovery.md)。公共HTTP、独立SDK和通用接入示例尚未交付;独立SIGNAL/TIMER等待重建继续实现。完整交付继续按[开发计划](08-development-plan.md)推进。
|
||||
|
||||
## 1. 四类操作
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
| ReviewTask | 核实本实例历史激活拥有的NEEDS_REVIEW任务,写入SUCCEEDED/FAILED、明确执行已结束和证据 | 不把查询请求成功解释成业务成功,不解除步骤或实例核查 |
|
||||
| ResolveStep | 将当前待核查/失败/取消叶子步骤核实为SUCCEEDED或FAILED,保存符合固定契约的逻辑结果 | 不重新执行旧任务,不清除实例核查或原停止意图 |
|
||||
| Continue | 在当前证据和步骤状态允许时解除实例核查,保存根接续 | 不解除显式paused,不延长截止,不撤销取消或失败结清 |
|
||||
| RetryStep | 为已确认失败/取消的TASK建立新的激活和关联任务,继续消耗原尝试预算 | 不重跑成功步骤,不改变输入/业务关联,不为POLL另起新轮次 |
|
||||
| RetryStep | 为TASK或POLL建立新的激活和关联任务,继续消耗原任务或原业务轮尝试预算 | 不重跑成功步骤,不改变输入/业务关联,POLL恢复不另起业务轮次 |
|
||||
|
||||
查询请求、外部业务结果和流程接续是不同事实。例如,查询任务核实为成功但返回PENDING,仍不能将POLL步骤核实为成功;POLL成功结论必须通过固定映射分类为SUCCEEDED。未知执行须先完成ReviewTask,再等待新版本结果进入内部Inbox并消费,才能确认步骤结论。
|
||||
|
||||
@@ -43,7 +43,7 @@ ResolveStep保存当前激活的新管理结论,审计记录前一状态、前
|
||||
|
||||
## 4. TASK重试预算
|
||||
|
||||
当前仅TASK支持RetryStep。要求没有取消或失败停止意图,实例和原任务绝对截止尚未到达,相关历史执行均已知失败或取消。核实实际尝试行数、任务attempt_count、连续激活序号、retry_of链、固定处理器/输入/队列/优先级和策略一致性。
|
||||
TASK恢复规则如下。要求没有取消或失败停止意图,实例和原任务绝对截止尚未到达,相关历史执行均已知失败或取消。核实实际尝试行数、任务attempt_count、连续激活序号、retry_of链、固定处理器/输入/队列/优先级和策略一致性。
|
||||
|
||||
- 新激活sequence递增;新任务retry_of指向前一任务,同一原任务只允许一个直接后继。
|
||||
- 新max_attempts = 固定定义max_attempts − 全部历史激活已用尝试数;首次尝试也计入。
|
||||
@@ -54,7 +54,7 @@ ResolveStep保存当前激活的新管理结论,审计记录前一状态、前
|
||||
|
||||
创建新任务后实例仍处于核查,门控保持关闭。操作者确认其他事项已处理后调用Continue,才允许新任务取得执行授权;原paused仍为true时还需正常RESUME。
|
||||
|
||||
POLL恢复仍需实现跨激活的原轮次归属、单轮剩余尝试及原查询截止传递。当前RetryStep明确拒绝POLL,禁止通过新建业务轮次规避耗尽的单轮预算。SIGNAL/TIMER逻辑结论可核查,但不通过此操作重新开始等待;恢复等待/查询的完整范围仍需后续实现与验收。
|
||||
POLL跨激活恢复已实现,保留原业务轮、同轮剩余尝试、查询总截止和该轮原任务截止;成功返回PENDING的轮次不能人工重查。附属最终信号等待沿用原契约/关联/截止并更换代次,详见[查询恢复](17-workflow-poll-recovery.md)。核查后已确认PENDING的显式等待接续仍需补齐;独立SIGNAL/TIMER逻辑结论可核查,等待重建仍待实现。
|
||||
|
||||
## 5. 停止与到期
|
||||
|
||||
@@ -68,6 +68,7 @@ POLL恢复仍需实现跨激活的原轮次归属、单轮剩余尝试及原查
|
||||
| --- | --- |
|
||||
| TASK效果未知,核实成功 | 读取当前实例/任务 → ReviewTask(SUCCEEDED) → 等待内部结果消费 → 读取当前版本 → ResolveStep(SUCCEEDED) → Continue → 后台接续 |
|
||||
| TASK已确认失败,原预算仍有余量 | 读取当前实例/步骤/激活 → RetryStep → 核对新任务及原截止 → Continue → Worker执行新任务 |
|
||||
| POLL请求失败且仍有预算 | RetryStep → 核对同业务轮和剩余尝试 → Continue;结果PENDING才按原间隔开下一轮 |
|
||||
| POLL次数耗尽,人工取得最终结果 | 核实历史请求均已结束 → ResolveStep(符合固定成功映射的结果) → Continue;原used_rounds不改变 |
|
||||
| 取消后出现UNKNOWN | ReviewTask → 等待消费 → ResolveStep → Continue → 原取消结清;不创建后继工作 |
|
||||
|
||||
|
||||
65
docs/17-workflow-poll-recovery.md
Normal file
65
docs/17-workflow-poll-recovery.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Weave 有界查询的人工恢复
|
||||
|
||||
状态:内部 `RetryStep` 已支持 POLL 新激活,保留跨激活的业务轮次、同轮剩余尝试和绝对截止;附属最终信号等待随新激活换代。核查后已确认 PENDING 的显式等待接续、独立 SIGNAL/TIMER 的等待重建仍待实现,公共实例/恢复 HTTP、独立 SDK 和可运行接入示例继续按[开发计划](08-development-plan.md)交付。验证范围见[阶段报告](reports/phase-5-poll-recovery.md)。
|
||||
|
||||
## 1. 业务轮次与请求尝试
|
||||
|
||||
查询成功且业务结果为 PENDING 时,后台按原间隔开启下一业务轮。请求失败、未知或结果不符合契约时,进入核查;人工恢复重查同一业务轮,不能通过换激活获得新的请求预算。
|
||||
|
||||
例如固定定义最多查询 3 轮,每轮最多尝试 3 次:
|
||||
|
||||
| 工作 | 激活 | 业务轮次 | 本任务尝试上限 | 沿用的截止 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 原查询请求失败,已用 1 次 | 1 | 1 | 3 | 第一轮原任务截止、原查询总截止 |
|
||||
| 人工恢复同轮 | 2 | 1 | 2 | 同上,人工操作不重新计时 |
|
||||
| 恢复请求成功返回 PENDING,间隔到达 | 2 | 2 | 3 | 新业务轮的任务截止受原查询总截止截短 |
|
||||
| 第二轮请求失败,已用 1 次,再人工恢复 | 3 | 2 | 2 | 第二轮第一次任务的绝对截止、原查询总截止 |
|
||||
|
||||
恢复前核验真实尝试行数、任务计数、原处理器/版本/策略/输入、业务键、互斥键、所有者、连续激活及 `retry_of` 链。每一业务轮的任务总数也不超过原单轮尝试上限,防止反复取消未开始任务而无限制造激活。一次成功查询已返回 PENDING 的轮次不能人工重试;轮次耗尽须核查最终事实或取消。若 UNKNOWN 经 ReviewTask 被核实为成功 PENDING,现有操作不会自动恢复等待;原预算内显式接续后续业务轮的操作仍需实现,不能借同轮 RetryStep 绕过间隔或次数。
|
||||
|
||||
## 2. 恢复前提和事务
|
||||
|
||||
沿用[人工核查约定](16-workflow-recovery.md):显式 `workflows:recover`、最新实例/步骤版本、当前激活、稳定操作键、原因、证据和 `safe_to_retry=true`。只有 NEEDS_REVIEW 实例中待核查、失败或取消的 POLL 可恢复。已有停止意图、实例/查询/原请求截止到达、次数耗尽或历史执行未知时拒绝。
|
||||
|
||||
UNKNOWN 必须先核实全部外部执行结束,经 ReviewTask 保存确定结果,并消费其新版本 Inbox 后再恢复。声明不能替代服务端的历史归属、执行、许可和未消费/隔离来源检查。
|
||||
|
||||
新激活、新 Pulse 任务、同轮记录、预算、最终信号等待、时钟、额度、审计和幂等回执同事务提交。新任务受当前应用及队列配额约束;满额、唯一性冲突或审计失败全部回滚。相同操作键并发重报只返回一个冻结回执,仍核验当前权限。
|
||||
|
||||
恢复后实例仍是 NEEDS_REVIEW,执行门控关闭;继续核查通过后显式 Continue,原 paused 为 true 时还需 RESUME。恢复不会撤销原取消/失败停止目标。
|
||||
|
||||
## 3. 数据与历史
|
||||
|
||||
[迁移 000022](../internal/storage/mysql/migrations/000022_workflow_poll_recovery.up.sql)为 `PollState` 新增:
|
||||
|
||||
| 字段 | 含义 |
|
||||
| --- | --- |
|
||||
| first_round | 当前激活保存的首个业务轮次。人工恢复沿用旧激活的最后业务轮编号 |
|
||||
| first_round_attempts_used | 该轮在此前激活已用的请求尝试数,从原单轮预算扣除 |
|
||||
|
||||
`used_rounds` 仍是从首次激活起的业务轮次编号,不是当前激活行数。当前激活轮次必须完整覆盖 `[first_round, used_rounds]`;正常进入下一轮时继续 `used_rounds+1`。查询总截止基于首次激活的创建时间,当前激活创建时间不成为新起点。同轮的新任务以 `retry_of` 关联前一任务,沿用该轮第一次任务的绝对截止。
|
||||
|
||||
旧激活状态、输出、任务结果、执行尝试、轮次及信号证据保留;旧查询预算关闭在途/后续检查点并保留原结清时间。来源事件仍固定原激活和任务,旧激活结果只记录 STALE_ACTIVATION,不能完成新任务。停止结清核验所有历史任务,轮次归属按各自的 `first_round` 和 `used_rounds` 检查。
|
||||
|
||||
迁移将历史数据补为 `first_round=1`、已用历史尝试为 0,不更改旧轮次、原截止、预算、状态版本及时间。新增两个 Go 字段和 SQL 列均有中文注释。当前共 35 个持久化实体、305 个直接字段声明;无外键、无级联删除。
|
||||
|
||||
升级需停止旧写入节点,再执行正式迁移并启动新版。旧节点不了解跨激活轮次与截止传递,不能在新节点创建恢复激活后继续混跑。
|
||||
|
||||
## 4. 最终信号的换代
|
||||
|
||||
POLL 带最终信号时,恢复创建同契约、同精确关联键、同原截止的新等待,目标激活代次加一。旧已消费信号及旧 winner 保留,不能自动成为新等待赢家。旧代次再次受理的信号保存为 REJECTED / STALE_ACTIVATION;新代次须重新提交有证据的信号。
|
||||
|
||||
当前代次仍有 PENDING 信号时,先消费这些事实,恢复拒绝直接丢弃。已有赢家时核对其受理证明与关联后保留历史。最终信号原截止已过时不重新开始等待。
|
||||
|
||||
这些规则仅覆盖 POLL 附属等待,不表示独立 SIGNAL/TIMER 重建已经开放。
|
||||
|
||||
## 5. 内部调用场景
|
||||
|
||||
| 场景 | 调用顺序 |
|
||||
| --- | --- |
|
||||
| 已知请求失败且仍有预算 | 读取当前实例/步骤 → RetryStep → 核对新任务及剩余预算 → Continue → Worker 执行 → 原查询分类逻辑接续 |
|
||||
| 请求 UNKNOWN | 核实外部执行结束 → ReviewTask → 等待 Inbox 消费 → 读取当前版本 → RetryStep → Continue |
|
||||
| 恢复后收到旧结果 | 内部 Inbox 消费只保存旧激活处置,不推进当前激活 |
|
||||
| 恢复后收到新最终回执 | 用新激活代次发送同契约信号 → 按原受理时间裁决并结清当前查询 |
|
||||
| 原轮次/请求预算或截止耗尽 | 拒绝新查询;按证据 ResolveStep 或继续取消/停止结清 |
|
||||
|
||||
实现入口是[内部恢复服务](../weave/recovery/service.go)和[POLL 存储事务](../internal/storage/mysql/workflow_poll_retry.go)。这些场景尚不是公共 SDK 用法;公共接口、可运行示例和生产拓扑验收仍须交付。
|
||||
34
docs/reports/phase-5-poll-recovery.md
Normal file
34
docs/reports/phase-5-poll-recovery.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# P5 有界查询跨激活恢复回归
|
||||
|
||||
日期:2026-09-18。范围为内部 POLL 人工重试及附属最终信号等待换代。核查确认 PENDING 后的显式等待接续、独立 SIGNAL/TIMER 等待重建、实例公共 HTTP/SDK、完整场景与 P6–P7 生产验收仍未完成,持续目标保持完整。
|
||||
|
||||
## 实现与边界
|
||||
|
||||
[查询恢复约定](../17-workflow-poll-recovery.md)将请求尝试与业务轮次分开。人工重试保留原业务轮编号和绝对截止,跨激活扣除真实尝试;成功 PENDING 才允许正常开启下一轮。已结束但未开始过的任务也受每轮任务数上限约束。旧结果只能作用于旧激活,旧信号赢家只保留历史,新等待使用新代次和原契约/关联/截止。
|
||||
|
||||
新激活、任务、轮次、预算、等待、时钟、额度、审计与回执同事务。UNKNOWN、待消费或隔离结果、有效尝试和许可、原停止意图、预算及截止仍由恢复规则约束;恢复后需显式 Continue 才解除核查门控。迁移000022只增加两个带中文注释的预算字段,平台仍为35个持久化实体、305个直接持久化字段声明,无外键、无级联。
|
||||
|
||||
## 环境与证据
|
||||
|
||||
本机 darwin/arm64、Go 1.27.1、Docker MySQL 8.4.10;每轮使用脚本创建的一次性隔离容器及数据库。
|
||||
|
||||
| 检查 | 结果 |
|
||||
| --- | --- |
|
||||
| 首批存储专项 | 新增9组查询恢复、原16组人工核查、时钟/信号、v9应用额度升级、新建Schema及v7无外键升级通过,`-race`,64.729秒 |
|
||||
| 扩展专项 | 12组查询恢复、真实v21预算升级、实际Orbit进程通过,`-race`,54.694秒;恢复13.14秒、升级4.46秒、实际进程35.64秒 |
|
||||
| 基础回归 | `make fmt test vet build`通过,退出0;包含独立SDK和两个业务示例模块 |
|
||||
| 完整隔离回归 | 整条脚本通过,退出0;存储全量208.573秒,实际流程进程包37.148秒,Worker SDK 92.526秒,最终SDK进程故障组97.279秒;19个SDK示例与2个独立业务示例全部通过 |
|
||||
| 模型注释 | 使用Go AST逐字段核对:305个带db标签的直接字段声明,缺中文说明0 |
|
||||
| SQL结构和文档 | 实际v22测试库外键0、无COMMENT业务字段0;932个本地链接与53段JSON检查通过 |
|
||||
|
||||
12组专项覆盖:同轮恢复后进入下一业务轮并再次恢复、同轮剩余尝试耗尽、成功PENDING不能绕过轮次上限、十路同键并发及撤权回执拒绝、审计失败全回滚、UNKNOWN先核查与消费、信号新代次和原截止、原请求截止耗尽、尝试计数与真实行数不符、零尝试激活上限、旧winner证据保留及禁止复用、满额/停止意图拒绝。
|
||||
|
||||
实际进程测试确认全部旧控制进程退出后创建同轮新激活,再由两个全新进程竞争接管;保留原请求截止和剩余2次尝试,收到PENDING后只创建一次下一业务轮,并最终成功。该测试累计16个任务、无额外查询或许可泄漏;此前TASK、停止、信号、TIMER等进程恢复用例也同时运行。
|
||||
|
||||
v21升级夹具用于验证迁移:保留旧轮次1/2、原预算、截止、revision及创建/更新时间,补入first_round=1和历史尝试0;非法恢复预算被CHECK拒绝。v9还原夹具同步删除v22新字段后走正式迁移;不修改历史迁移校验和。所有关联继续由服务端事务检查。
|
||||
|
||||
证据实现见[查询恢复专项](../../internal/storage/mysql/workflow_poll_recovery_integration_test.go)、[v21升级专项](../../internal/storage/mysql/workflow_poll_recovery_upgrade_integration_test.go)和[真实进程专项](../../internal/storage/mysql/workflow_runtime_process_integration_test.go)。
|
||||
|
||||
完整复现入口是[隔离MySQL脚本](../../scripts/test-mysql.sh)。缺少一次性DSN或实际二进制而跳过的用例不计为通过。本地双进程和单MySQL故障验证不替代生产复制、切换、备份恢复、容量或RPO/RTO验收。
|
||||
|
||||
完整回归结束后,一次性测试容器均已由脚本清理。最终检查932个本地链接、53段JSON,错误0;`git diff --check`通过。本轮执行逻辑在完整回归开始后未再修改,后续只补充模型说明与文档中的剩余范围。
|
||||
Reference in New Issue
Block a user