test: cover dispatch loss and workflow commit fault boundaries
This commit is contained in:
74
docs/reports/phase-6-fault-boundaries.md
Normal file
74
docs/reports/phase-6-fault-boundaries.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# P6 首批:派发未送达与事务提交故障边界
|
||||
|
||||
日期:2026-09-18。本批补A04、W01/W13的精确故障切点,并补W16最终回执、旧查询结果与下一轮唤醒的竞争。工具只编译进测试二进制,生产服务、SDK运行代码、接口、模型和迁移不增加故障开关;数据库继续禁止外键。
|
||||
|
||||
## A04:派发已提交,Worker尚未收到
|
||||
|
||||
[公共SDK进程测试](../../sdk/go/dispatch_process_integration_test.go)使用[真实WS故障网关](../../sdk/go/worker_integration_test.go)。网关已从真实Orbit收到`task.assign`帧,但在转交业务Worker之前截留它,并阻止重连。
|
||||
|
||||
测试通过独立HTTP连接确认同一任务已处于LEASED、存在一次持久尝试、authorized_at为空。Worker实际处理器调用数仍为0。随后强杀原Orbit并Wait确认退出;该帧始终没有交给Worker,网关丢弃它。另起真实Orbit节点并按原提交键核对回执。
|
||||
|
||||
保持Worker离线,等待原30秒租约自然到期,不修改数据库时钟。新节点将未授权尝试记录为EXPIRED,ended_at不早于原lease_until,原任务回到WAITING且没有未知副作用标记。恢复WS后完成原任务:
|
||||
|
||||
- 业务处理器恰好执行1次;总尝试恰好2次,第一次未获授权,第二次SUCCEEDED。
|
||||
- 沿用原任务、提交回执、总截止和2次尝试预算;RECONCILE_ONLY策略保持。
|
||||
- 并发上限为1的队列可重新派发,证明旧预占已释放;完成后的未终结任务额度为0。
|
||||
|
||||
这条证据针对“未送达业务Worker”。帧已到测试网关,不声称平台从未向网络写过该帧,也不将已送达但未开始的场景混为同一切点。SDK不获得网关保存的旧执行秘密。
|
||||
|
||||
## W01/W13:MySQL COMMIT前后真实断线
|
||||
|
||||
[MySQL包代理及八个场景](../../internal/storage/mysql/commit_fault_integration_test.go)只允许连接一次性、明文、loopback测试数据库,不修改生产TLS配置,不输出SQL、凭据或业务正文。按MySQL包头逐包转发,识别真实COM_QUERY COMMIT:
|
||||
|
||||
| 切点 | 代理实际动作 | 独立数据库连接应观察到的事实 |
|
||||
| --- | --- | --- |
|
||||
| BEFORE | 不把COMMIT转交MySQL,关闭连接 | 尚未提交的状态、任务、身份和消费确认全部回滚 |
|
||||
| AFTER | 收到真实MySQL成功包,核验IN_TRANS已清除;不把确认交给驱动,关闭连接 | 数据已经完整提交,调用方收到连接错误,不能当作回滚后换身份 |
|
||||
|
||||
四种事务各覆盖两个切点:启动实例及首批任务、结果消费及创建后继、PENDING结果及建立下一轮等待、下一轮任务及轮次预算递增。故障调用必须返回错误,同时代理必须证明到达所选切点;不能仅因请求报错就推断发生过COMMIT。
|
||||
|
||||
通过不经过故障代理的连接读取真实表,检查实例/任务数量、Inbox处理确认、查询等待或轮次原子性。随后使用新运行器处理原候选,或用原启动键重报。最终每个场景恰好两个任务和两次尝试,无待处理Inbox或许可遗留,原版本、原流程/查询截止及尝试预算保持。PENDING等待仍从原结果事件时间计算,不从重报时间重新开始。
|
||||
|
||||
这证明数据库连接在提交边界断开的恢复行为,不等于MySQL进程宕机、复制切换、丢失已确认事务或磁盘故障验收。它也不将HTTP回执丢失冒充数据库提交结果不明。
|
||||
|
||||
## W16:最终回执、旧查询结果、下一轮同时竞争
|
||||
|
||||
[六种入队顺序](../../internal/storage/mysql/workflow_final_signal_race_integration_test.go)使用真实MySQL锁等待确认三个事务都已重叠,再等原下一轮时间自然到达后放行。参与者分别是最终DONE信号受理、上一轮PENDING结果的重复消费、下一轮时钟。
|
||||
|
||||
上一轮必须已经保存等待,下一轮才可能到期。因此此处结果参与者是旧结果重放,测试明确保留这个因果关系,不构造不可能同时存在的“未提交PENDING和已到期下一轮”。已授权查询与新结果、冲突/未知结果的处理另由[现有信号运行回归](../../internal/storage/mysql/workflow_signal_runtime_integration_test.go)及真实进程恢复覆盖。
|
||||
|
||||
观察到两类合法顺序:最终信号先受理时,不创建第二轮;下一轮先创建时,最终信号取消尚未授权的第二轮查询并收集其结果。两者都只执行第一轮查询和一个后继任务,只完成一个等待。再次投递旧PENDING和旧时钟不能重新打开轮次或多建后继;原信号回执、版本、截止和精确输出保持。
|
||||
|
||||
## 复现和验证
|
||||
|
||||
```sh
|
||||
make fmt test vet build
|
||||
make integration
|
||||
```
|
||||
|
||||
标准脚本的存储组自动执行`TestIntegrationWorkflowCommitFaults`与`TestIntegrationWorkflowFinalSignalRace`;原服务退出后的Worker进程组自动执行`TestIntegrationWorkerProcessUndeliveredAssignment`。无需额外生产依赖或手工开启故障环境变量。
|
||||
|
||||
定向环境:macOS arm64、Go 1.27.1、Docker MySQL 8.4.10、独立临时数据库及真实Orbit进程。最终定向存储组14个子场景退出0(21.100秒),A04进程组退出0(34.080秒)。MySQL驱动的预期EOF来自代理确实切断COMMIT连接,不是测试失败。首次编译纠正了测试误用的队列资源方法,改用已公开的GetQueue;未因此增加接口或扩大发放权限。
|
||||
|
||||
基础`make fmt test vet build`退出0。最终标准全量回归退出0:23个可运行SDK示例、2个独立业务模块,以及完整存储、协议与真实进程恢复链路均通过。标准脚本使用竞态检测;本批测试源码自启动完整回归后未再修改。
|
||||
|
||||
| 标准回归分组 | 结果与测试耗时 |
|
||||
| --- | --- |
|
||||
| 存储及迁移全部场景 | 退出0,266.966秒;包含八个COMMIT切点及六个W16入队顺序 |
|
||||
| 原流程运行器进程全停/接管 | 退出0,49.022秒 |
|
||||
| 独立业务Inbox | 退出0,35.638秒 |
|
||||
| 独立业务Outbox | 退出0,34.167秒 |
|
||||
| Worker/结果订阅进程故障 | 退出0,128.097秒;包含A04自然租约到期场景32.72秒 |
|
||||
| 公共SDK流程暂停全停/恢复 | 退出0,13.845秒 |
|
||||
|
||||
以上耗时仅用于复现核对,不是吞吐或延迟指标。无外键升级回归同时确认:历史70个外键全部移除,323个原索引组成部分及任务数据保留,当前外键为0,重新引入外键的结构漂移被拒绝。模型和中文注释要求没有改变。
|
||||
|
||||
本批证据与[前一批竞争/全停回归](phase-4-5-races.md)共同补齐P4/P5功能阶段核对所列的具体缺口;[P4/P5报告](phase-4-5.md)据原功能清单记录阶段验收通过。P6进行中,P7及完整首版交付尚未完成。
|
||||
|
||||
最终文档检查:1184个本地链接、68个JSON块,错误0;`git diff --check`通过。
|
||||
|
||||
## 保留的生产门槛
|
||||
|
||||
本批关闭上述具体切点缺口,不代表故障模型或负载已穷尽。完整首版仍需运行指标/告警、可轮换凭据及安全重绑、历史保留/归档、慢消费者和重连风暴、六类容量负载、MySQL失联/主节点切换、备份恢复、跨故障域部署、SDK发布兼容和完整接入示例。
|
||||
|
||||
阶段范围和下一步见[持续计划](../08-development-plan.md)、[P4/P5核对](phase-4-5.md)与[原生产验收门槛](../05-production-acceptance.md)。当前单机数据库证据不能换算成生产HA、RPO/RTO或百万企业容量承诺。
|
||||
Reference in New Issue
Block a user