64 lines
6.5 KiB
Markdown
64 lines
6.5 KiB
Markdown
# Weave 持久化定时等待与查询轮次
|
||
|
||
状态:TIMER到期推进和POLL后续业务轮次已接入Orbit后台运行器。复用MySQL和既有待续索引,不增加外部调度服务或数据库外键。[SIGNAL消费与查询最终信号竞争](14-workflow-signals.md)已进一步接入;实例公共HTTP/SDK以及完整控制/人工恢复仍未交付。
|
||
|
||
## 1. 时钟和恢复身份
|
||
|
||
`weave_pending_advances`同时保存ROOT、TIMER、SIGNAL、POLL四类检查点。唯一范围为命名空间、实例和步骤;时钟检查点额外固定当前激活ID,避免旧激活唤醒新工作。扫描只提供候选,实际推进仍须持锁核验固定版本、父记录、步骤/激活状态、任务所有者、门控和原始预算。
|
||
|
||
| 检查点 | 到期时间来源 | 推进结果 |
|
||
| --- | --- | --- |
|
||
| ROOT | 分批推进或暂停/满额后的下一检查时间 | 重新计算最多32项步骤变更 |
|
||
| TIMER | 激活时保存的等待截止 | 完成原等待或记录超期核查,再有限推进 |
|
||
| POLL当前轮次仍在途 | 查询节点的原绝对截止 | 保留结果收集或关闭新执行门控,不启动重叠轮次 |
|
||
| POLL上一轮业务PENDING | 上一轮权威结果发生时间加固定间隔,受查询截止限制 | 若允许且有额度,同事务创建下一轮任务 |
|
||
|
||
每个候选遵守[运行器事务顺序](12-workflow-runtime.md):身份、应用额度、排序队列、实例、门控和子记录。多个Orbit节点竞争同一数据库记录,不能凭本地时间或内存缓存取得推进权。扫描失败回滚并按候选版本延后重查,既有结果和预算仍保留。
|
||
|
||
TIMER由待续表直接唤醒,不创建Pulse业务任务,也不占Worker执行许可。旧模型的`wake_task_id`当前保持空;后续若改变这一约定,需要独立迁移与兼容验证。
|
||
|
||
## 2. 定时等待
|
||
|
||
激活时保存开始时间及`min(开始时间 + delay_ms, 实例总截止)`。恢复时重新验证这条等式,不能从重启或继续时间重新计时。
|
||
|
||
- 原计划等待时长能在实例总截止内结束:到期保存SATISFIED及步骤SUCCEEDED,输出为JSON `null`。
|
||
- 后续步骤才激活TIMER,导致剩余实例时长不足:到总截止保存EXPIRED、步骤及实例NEEDS_REVIEW,不能把被截短的等待当作成功。
|
||
- 暂停期间已到期的等待仍可收集完成;后继保留ROOT待续,直到控制状态允许。暂停不延长截止。
|
||
- 全部进程停止后才被扫描:使用原到期时间。若整个流程已能由有效的到期事实完成,可以整理完成;若还需启动新步骤且实例总截止已过,则进入核查。
|
||
|
||
等待结清、步骤状态、后继任务或ROOT检查点、事件和审计同事务。审计失败不会留下已完成等待或部分后继。
|
||
|
||
## 3. 有界查询与请求重试
|
||
|
||
一次业务查询轮次对应一个Pulse任务。当前任务成功返回PENDING后,内部结果事务保存WAITING、清除`current_task_id`、记录`next_poll_at`并更新POLL检查点。成功查询仍在处理和请求执行失败使用不同预算:
|
||
|
||
| 场景 | 业务轮次 | Pulse尝试 |
|
||
| --- | --- | --- |
|
||
| 已知可重试请求失败 | 不增加,仍为原任务 | 按该任务冻结策略增加 |
|
||
| 查询成功返回PENDING且未耗尽预算 | 到固定间隔后创建下一任务,增加1 | 新一轮从自身首次尝试开始 |
|
||
| DONE等声明成功结果 | 结清当前查询节点 | 不再启动下一轮 |
|
||
| 单轮失败/效果未知/非法结果/业务核查值 | 停止正常推进并保存核查事实 | 不通过创建新轮次绕过原尝试上限 |
|
||
| 轮次耗尽或总截止到达 | 不增加,进入核查 | 原在途任务仍需收集实际结果 |
|
||
|
||
创建下一轮前校验轮次连续、当前无在途任务、上一轮已经确认为POLL_PENDING。复用首轮已解析的精确输入、业务键、资源互斥键以及固定版本的处理器、契约、优先级和重试策略;不重新解释已完成步骤的表达式。任务绝对截止仍取自身时限、查询总截止和实例总截止的较早者。
|
||
|
||
新任务、所有者和门控、轮次记录、已用轮数、当前任务、步骤状态、下一检查点、事件及审计同事务。插入轮次或审计失败会连同任务及额度一起回滚。应用/队列满额、暂停或身份停用仅延后检查;不消耗新轮次,不改变原截止。
|
||
|
||
## 4. 截止与已落库结果的竞争
|
||
|
||
截止扫描发现当前任务已经有终态或核查结果,但Inbox还未消费时,保留时钟并优先等Inbox按原事件时间裁决。不能用扫描发生时间否定已按时可靠受理的成功结果。
|
||
|
||
当前任务仍在途且查询总截止已到时,实例转NEEDS_REVIEW并关闭新执行门控;步骤保持ACTIVE、轮次保持当前任务引用,继续收集Pulse结果。时钟不释放执行许可,也不假定外部请求已经停止。Pulse恢复将失联执行记录为UNKNOWN后,内部消费再结清当前查询记录,保留核查状态。
|
||
|
||
最终信号与在途查询的竞争已按[信号运行约定](14-workflow-signals.md)接入:保存赢家后等待Pulse查询结清,不能提前释放许可或覆盖未知效果。实例及信号公共HTTP/SDK尚未开放。
|
||
|
||
## 5. 升级和验证
|
||
|
||
[迁移000019](../internal/storage/mysql/migrations/000019_workflow_clock_checkpoints.up.sql)仅回填旧实例当前激活的TIMER/POLL检查点:定时等待使用原deadline,等待查询使用原next_poll_at,在途查询使用原查询deadline。已有检查点不覆盖,终态实例及旧激活不回填;不新增表、字段、索引、外键或级联。
|
||
|
||
升级顺序为停止旧写入节点 → 应用全部迁移 → 启动新节点。旧节点可能消费PENDING结果却不会创建新的时钟检查点,因此不能与新版混跑。历史结构损坏或缺少完整定义的记录即使形成候选,也必须经运行器校验才能推进。
|
||
|
||
[存储回归](../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)。
|