Files
orbit/docs/reports/phase-3-result-subscription-core.md

7.4 KiB
Raw Permalink Blame History

P3 可靠结果订阅持久化核心回归

验证日期:2026-09-17。本阶段完成结果日志、订阅和交付的服务/存储核心;HTTP/WSS、独立 SDK、Inbox 示例和订阅进程故障用例尚未交付。P3 与持续开发目标继续进行,不视为完整订阅能力验收。

1. 实现内容

核心设计与边界 对应以下实现:

  • 迁移 000013 增加命名空间结果流和不可变结果快照,扩展订阅窗口、游标、交付预算及证明摘要。最终 Schema 无外键,模型和 SQL 字段注释同步。
  • 结果日志 接入原状态事件事务;成功、已知失败、取消和需要核查四类结果同事务追加快照。每个命名空间独立串行分配序号,不按随机 ID 或最大自增 ID 推断提交顺序。
  • 订阅服务 和 订阅存储 实现范围权限、凭据所有者、单队列冻结过滤、历史边界、幂等创建、暂停/继续、64 个订阅上限。
  • 交付存储 实现有限批次物化、未确认窗口、30 秒租约、连接容量、到期退避、次数耗尽保留、最新证明隔离、重复/迟到确认和人工追加预算。每次授权及管理确认有审计,秘密只保存摘要。
  • 数据模型目前共 35 个实体、289 个直接声明的持久化字段;逐字段中文注释检查无遗漏。SQL 模型映射由真实数据库回归校验。

2. 环境与命令

macOS 本机、Go 1.27.1、Docker MySQL 8.4.10、一次性数据库、回环 HTTP/WSS。使用随机测试凭据,测试清理自己的容器;不连接既有业务数据库。

make fmt test vet build
make integration
cd sdk/go
GOWORK=off go test -race ./...

上述检查均通过。模型、接口、SDK、示例与故障检查分别执行;没有数据库环境的普通 go test 会跳过集成,不能替代本次真实数据库验证。

分组 本次结果
全部 MySQL 集成 PASS,85.486 秒
新增订阅核心 15 组场景 PASS,3.49 秒
新增提交顺序/创建边界 3 组 PASS,0.63 秒
v12 订阅迁移升级 PASS,3.79 秒
SDK Worker 协议及运行器 PASS,89.166 秒
SDK 计划生命周期 PASS,5.626 秒
SDK 队列 / 应用资源 PASS,4.501 / 1.386 秒
既有七项真实进程故障 PASS,28.528 秒
既有十二个完整 SDK 示例 全部通过
fmt / race / vet / build / 独立 SDK 模块 全部通过

耗时仅记录本地回归,不代表生产吞吐、SLO、容量或高可用结论。

3. 新增正确性和竞争证据

订阅数据库用例 验证:

  1. 来源重复回报不会重复追加结果;省略游标从创建边界之后开始,显式 0 可回放现存结果日志。类型过滤会安全推进扫描位置。
  2. 结果 9007199254740993 保留原数值文本,<&> 不被无谓扩大;后续改动任务结果不会改变已保存快照。数据库拒绝 UPDATE 结果日志。
  3. 不同命名空间、同命名空间另一凭据、移除队列范围、缺少独立动作及凭据撤销均被阻止。同一个幂等键不会跨所有者泄漏原回执。
  4. 未确认窗口为 1 时,仍可提交后续 3 条结果;确认后按日志逐条追赶,无跳过或重复扣减。持有订阅行锁期间,独立任务取消仍在限定时间内提交结果。
  5. 12 个消费者争抢同一条交付,只有一个获得有效租约。12 次并发确认中只有一次首次生效,所有响应保留相同确认时间,只有一条确认审计。
  6. 丢弃存储服务对象后,重新创建服务仍从数据库恢复相同交付和事件身份。租约到期后退避,新的发送增加次数和代次并更换秘密;旧证明失效。
  7. 次数耗尽后保留 EXPIRED 及积压占用。最新证明未被新代次替换时允许迟到确认,重复确认返回原回执。
  8. 人工重试增加预算而不重置次数、代次或事件身份;相同管理身份重报不重复追加。错误状态或版本被拒绝。
  9. 暂停阻止新发送,但允许在途 ACK;恢复后继续接收后续结果。单连接容量在数据库事务内执行,确认后释放容量。
  10. 12 次迟到 ACK 与新领取竞争,最终只存在一个有效确认,旧证明不能确认新代次,也不会泄漏窗口额度。
  11. 注入交付 INSERT 失败,交付记录、扫描位置和 pending_count 一起回滚;注入审计 INSERT 失败,ACK、确认时间和计数一起回滚。
  12. 注入结果日志 INSERT 失败,任务状态、原状态事件、流序号及应用额度一起回滚;原请求身份可以重报成功。
  13. 安全重试不产生最终结果通知;最终失败、UNKNOWN 及执行失联恢复的核查结果进入结果日志。
  14. 未来游标、缺失历史和订阅数量超限分别返回明确错误。秘密原文不进入确认审计。

提交顺序用例显式保持第一个生产事务未提交,同时启动另一个事务。消费者看不到越过未提交事务的较大序号,且不等待生产者流锁。首事务提交时依次获得 1、2;首事务回滚时后一个获得 1,无非事务性空洞。创建“从现在开始”的订阅必须等前一个生产事务完成,并正确捕获最终提交边界。

回归修正了首次物化后的时钟边界及复合幂等作用域超过既有 64 字符的问题,最终完整套件重新通过。

4. 升级和无外键证据

v12 专项升级 重建真实旧 Schema,保留已有任务事件及数值精度;旧占位订阅禁用且 queue_id 为空,不自动取得消费权限。旧交付已使用 25 次、代次 25,升级后原值不变,预算至少覆盖已用次数。重复迁移安全,未凭空生成历史结果快照。

v7 无外键升级 继续验证原有 70 个外键移除后为 0,325 项原索引列定义保留、任务数据不变,手工引入外键时启动检查拒绝。新结果表和交付扫描索引作为新增内容单独排除于“原索引不变”比较;没有跳过原索引的校验。

v4 安全重试及 v9 应用配额回填和在途释放回归仍通过。当前迁移新增结果日志,需要停止旧写入节点后升级;不支持旧二进制持续写入但遗漏新日志的混跑部署。

5. 后续验收边界

  • 尚未开放订阅 HTTP/WSS 路由,未声称新订阅能由独立 SDK 调用。本次十二个示例及七项强杀故障覆盖的是既有能力。
  • 本次“恢复服务对象”只验证交付权威状态不在内存,不能替代订阅 WSS 断路、ACK 响应丢失或真实节点进程强杀;这些将在传输层和 SDK 接入后验证。
  • 首版按领取触发该订阅的租约恢复,没有独立订阅后台清扫。暂停或没有消费者时,过期 LEASED 可能延迟转为 EXPIRED。
  • 未确认交付窗口有限,来源日志和已确认历史目前无自动清理,积压仍消耗存储。生产容量告警、保留/清理、监控及凭据轮换属于 P6。
  • 命名空间流锁热点、结果大小和数据库写放大,以及 MySQL 故障切换、跨故障域部署、RPO/RTO 仍需真实目标环境测试。