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

83 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# P3 结果订阅通信与管理 SDK 回归
验证日期:2026-09-17。已接通 [订阅 HTTP/WSS](../api/subscriptions.md)、独立管理 SDK 和 [管理示例](../examples/subscriptions.md)。消费连接 SDK、自动重连、持久化 Inbox 场景以及订阅真实进程强杀仍未完成,P3 和持续目标继续进行。
## 1. 本阶段交付
- [HTTP 路由](../../internal/transport/httpserver/events.go):订阅创建、队列范围分页、当前状态、带版本启停;交付分页、冻结结果详情、EXPIRED 追加预算。
- [查询存储](../../internal/storage/mysql/event_queries.go):按认证所有者、命名空间和父资源范围读取,分页游标绑定类别、过滤和凭据。交付详情不暴露证明原文或摘要。
- [迁移 000014](../../internal/storage/mysql/migrations/000014_delivery_history.up.sql):为交付创建时间及可选状态过滤添加索引,不改业务字段、已有迁移或外键规则。模型仍为 35 个实体、289 个带中文注释的持久化字段。
- [事件 Hub](../../internal/transport/httpserver/event_hub.go):独立 orbit.events.v1 入口,凭据、订阅和队列授权;hello、冻结快照交付、ACK、心跳、会话校验、断线恢复和有界关闭。
- 每节点 128 条事件连接;异步领取池 4 个全局在途、同应用 1 个在途、等待加在途总量 128,按认证应用及订阅轮转。控制收发不被同连接的慢领取阻塞。连接容量仍由持久化租约校验。
- [严格解码](../../internal/transport/httpserver/event_codec.go) 与 [公开 Schema](../../protocol/eventsv1/events.schema.json):方向、必填、字段精确大小写、规范 uint64、证明格式和消息大小;JSON 重复键、伪造响应字段或错误会话被拒绝。
- [管理 SDK](../../sdk/go/subscriptions.go) 与 [独立 DTO](../../sdk/go/subscription_types.go):七个管理/查询方法及类型,保留大整数和显式布尔控制,不依赖服务端或数据库包。
- [完整管理例子](../../examples/subscriptions/main.go) 已纳入统一隔离环境脚本。原始 WSS 测试辅助代码不作为正式消费 SDK 对外提供。
## 2. 验证环境与结果
macOS、Go 1.27.1、Docker MySQL 8.4.10、一次性数据库、两个 httptest TLS 节点和真实 Orbit 进程。回归随机凭据不打印,脚本结束清理自己的容器。
```sh
make fmt test vet build
make integration
cd sdk/go
GOWORK=off go test -race ./...
```
| 分组 | 本次结果 |
| --- | --- |
| 全量 MySQL 集成 | PASS,90.688 秒 |
| 新 HTTP/WSS 七组场景 | PASS,8.42 秒 |
| 原订阅核心 / 提交顺序 | PASS,3.41 / 0.59 秒 |
| SDK Worker 协议和运行器 | PASS,87.434 秒 |
| SDK 计划生命周期 | PASS,5.645 秒 |
| SDK 队列 / 应用额度 | PASS,4.526 / 1.403 秒 |
| 新订阅管理 SDK | PASS,32.16 秒,包总计 33.391 秒;包含实际 30 秒租约 |
| 既有七组真实进程故障 | PASS,27.534 秒 |
| 完整 SDK 示例 | 13 个全部通过 |
| fmt / race / vet / build / 独立 SDK 模块 | 全部通过 |
完整套件后补充交付正向翻页、跨订阅/命名空间详情拒绝及 Schema uint64 上界一致性检查;对应专项数据库与传输回归再次通过,28.651 秒。文档六个完整 WSS 消息也通过公开 Schema 校验。普通不带外部环境的 go test 会跳过集成,不能替代这些证据。
## 3. HTTP 与 WSS 实际验证
[真实数据库与 TLS 测试](../../internal/storage/mysql/event_transport_integration_test.go) 覆盖:
1. HTTP 创建/原键回执、显式 enabled、暂停继续、规范计数字符串、非法/重复查询参数;订阅与交付的稳定分页,游标不能换过滤范围。
2. 交付详情只能从正确的命名空间、所属凭据与订阅读取。JSON 不包含 lease_secret 或 token_digest;人工追加预算保留原身份、次数与幂等回执。
3. 握手拒绝缺失凭据、仅有 Worker 权限、错误子协议、URL 参数与跨来源 Origin。事件协议与 Worker 协议隔离。
4. WSS 交付接近 240 KiB 的结果,包含 9007199254740993 和大量 `<&>`,接收内容保持精确,帧仍在 512 KiB 以内。所有真实收发帧都通过方向对应的 Schema。
5. 容量 1 时即使存在第二条结果也只有一个有效交付租约;心跳正常,确认释放容量后继续派发。重复 ACK 使用原确认时间、无重复扣减。
6. 节点 A 断线后节点 B 恢复同一交付及事件,产生更大的代次和新秘密,拒绝旧证明。这里通过测试数据库提前设置到期验证路径;自然到期由独立 SDK 测试覆盖。
7. 消费者发送 ACK 后,查询数据库确认已提交,再丢弃未读取的响应并关闭连接。新节点使用原证明重报返回 deduplicated=true、原时间和唯一确认审计。
8. 已建立连接中的凭据撤销生效;错误 session_id 按 1008 关闭。关闭 Hub 保留已落库租约,拒绝新连接,另一节点仍能核对原证明。
[节点保护测试](../../internal/transport/httpserver/event_hub_test.go) 人为挂起领取直到 context 取消。在领取仍阻塞时,控制心跳在有界时间内回复;连接满额返回 429 和 Retry-After,断开后释放槽位,关闭时取消在途领取并清空槽位。测试将连接容量缩为 2 以减少资源,另外断言默认值为 128。
[解码与文档契约测试](../../internal/transport/httpserver/event_codec_test.go) 验证请求不能携带 reply_to/error/错误会话字段,拒绝缺失显式控制意图、重复键和别名。Schema 与实际解码都接受 uint64 最大值并拒绝溢出、零执行代次和前导零;HTTP 起始游标另外允许 "0"、null 或省略。
## 4. 独立 SDK 与示例证据
[SDK 管理集成](../../sdk/go/subscriptions_integration_test.go) 在真实进程上创建独立队列及订阅,执行 Create/Get/List/Configure;产生取消结果后通过测试 WSS 辅助连接领取一次并断开。另一个连接保持可领取状态,测试等待真实 30 秒租约到期,没有改数据库时间。
随后 SDK 通过 ListEventDeliveries 查到 EXPIRED,GetEventDelivery 读到冻结结果和已用次数;RetryEventDelivery 带版本追加一次预算,同键重报不再追加。下一次 WSS 交付保留事件和交付 ID、代次为 2,确认后 SDK 查到 ACKED、pending_count=0,配置 revision 未被消费计数污染。
[SDK 线格式测试](../../sdk/go/subscriptions_test.go) 核对显式 from_sequence=0 编码为字符串而不丢失,enabled=false 不被省略,9007199254740993 版本往返精确,非法路径和超限分页不发起网络请求。
管理示例实际输出(ID 每次不同):
```text
subscription=<本次订阅ID> duplicate=true resumed_revision=3
final_enabled=false revision=4 pending=0
```
13 个完整示例为 health、tasks、worker-protocol、worker、history、retry、schedules、cancellation、resources、keyed-concurrency、priority、subscriptions、application-resources。原七项进程故障覆盖的是任务/Worker/计划/额度/优先级等既有能力,不能当作新订阅已完成进程强杀验收。
## 5. 升级与尚未验证事项
- 真实 v7 升级继续保留 325 项原索引列定义,70 个历史外键最终为 0,错误手工外键仍被就绪检查拒绝。新交付分页索引作为新增项处理;v4、v9、v12 升级与模型映射回归通过。
- 完整事件连接 SDK、自动心跳/重连、持久化 Inbox 示例与真实节点进程强杀,仍是 P3 剩余工作。此阶段不把管理 SDK 或测试 WSS 辅助代码算作已经交付消费 SDK。
- 当前按启用订阅领取触发租约恢复;独立后台清扫、历史保留/清理、容量告警和安全凭据重新绑定未交付。
- 消费至少一次;业务效果需要接收方以事件 ID 去重并事务保存,再 ACK。连接关闭不能物理撤回已发送内容,也不提供业务恰好一次保证。
- 当前连接/领取上限是节点保护值,没有证明百万接入规模的吞吐、跨节点公平、全套请求治理或生产高可用。MySQL 故障切换、备份恢复、RPO/RTO 与目标容量仍需 P6 实测。