64 lines
4.9 KiB
Markdown
64 lines
4.9 KiB
Markdown
# Worker v1 机器可读契约
|
||
|
||
子协议为 `pulse.worker.v1`,消息中 `protocol_version` 为 `"1"`。完整文件:[worker.schema.json](../../protocol/workerv1/worker.schema.json),使用 JSON Schema Draft 2020-12。业务含义、超时及恢复方式见 [Worker 接口手册](worker.md)。
|
||
|
||
文件中的 $id 是契约标识,不表示该 URL 已部署下载服务。仓库文件是当前发布载体;回归使用本地嵌入文件,不访问远程 Schema。
|
||
|
||
## 校验入口
|
||
|
||
Schema 根接受双向消息,调用方应根据方向选择更严格的定义:
|
||
|
||
| JSON Pointer | 用途 |
|
||
| --- | --- |
|
||
| `#/$defs/clientFrame` | Worker → 服务端的所有请求 |
|
||
| `#/$defs/serverFrame` | 服务端 → Worker 的所有报文 |
|
||
| `#/$defs/helloFrame` | 注册请求,不允许 session_id、reply_to 或 error |
|
||
| `#/$defs/capacityFrame` | 容量及排空声明,sequence/capacity/drain 均必填 |
|
||
| `#/$defs/resumeFrame` | 尝试归属恢复请求 |
|
||
| `#/$defs/startFrame`、`renewFrame`、`finishFrame` | 开始、续租、结果报告 |
|
||
| `#/$defs/welcomeFrame`、`assignmentFrame` | 注册确认与主动派发 |
|
||
| `#/$defs/ackFrame`、`errorFrame` | 操作确认与公开错误 |
|
||
|
||
除首条 hello 外,请求必须提供当前 session_id。请求不得包含响应专用字段,包括 `reply_to:""` 或 `error:null`。主动派发没有 reply_to;操作响应通过 reply_to 关联原消息。error 在注册失败时不带 session_id;会话内错误带 session_id,主动致命错误不带 reply_to。
|
||
|
||
ACK 的 body 根据原请求选择:worker.capacity → welcome,worker.resume → lease,task.start/renew/finish → commandResult。Schema 可以检查三个 body 形状,消息关联与正确分支由连接状态检查;不能仅凭一个独立 ACK 判断它是否对应调用。
|
||
|
||
## 字段和兼容规则
|
||
|
||
- 已声明对象使用 additionalProperties=false,业务 payload/result 内部字段由接入方定义。
|
||
- 结构体必填字段必须显式提供,包括 capacity=0、drain=false;缺少字段不能被解释为调用者明确选择零值。
|
||
- epoch、sequence、revision 为规范十进制字符串:范围 1–18446744073709551615,无前导零和正号。SDK 使用 uint64,线上使用字符串。
|
||
- instance_secret/lease_secret 必须是 32 字节秘密的严格无填充 base64url,长度 43;知道资源 ID 无法替代秘密。
|
||
- 结果为非 null JSON;FAILED/UNKNOWN 必须携带稳定 error_code;SUCCEEDED 省略或使用空 error_code。
|
||
- finish.retryable 为可选布尔值,默认 false;true 仅允许 FAILED,Schema 与服务端都校验。派发任务可带 effect_uncertain=true,表示此前授权执行的效果尚未核实。业务重试条件见 [安全重试](retries.md)。
|
||
- 返回时间使用 UTC RFC 3339,最多微秒精度。验证器应开启 format 断言以校验实际日历日期。
|
||
|
||
P2 收紧了开发期此前允许的省略控制字段、非规范计数字符串和数组内字段别名。当前 SDK 一直发送完整规范字段,不需迁移;其他自研客户端应按本文件更新。SDK 尚未发布首个版本。将来扩展消息类型或改变字段语义必须同时更新 Schema、服务端、SDK 与兼容回归。
|
||
|
||
## Schema 与运行时的边界
|
||
|
||
Schema 检查已解析的 JSON 结构。以下约束必须在原始字节或持久化事务层另外校验:
|
||
|
||
| 约束 | 实际执行位置 |
|
||
| --- | --- |
|
||
| 文本帧、512 KiB 总帧限制 | WS 读写与解码入口 |
|
||
| 重复键、无效 UTF-8、孤立代理项、32 层嵌套 | 严格 JSON 扫描器,不能先交给会替换非法字符的解析器 |
|
||
| 结果 256 KiB、精确数字文本/指数范围 | 结果校验器;JSON Schema 的字符数不等于编码字节数 |
|
||
| JSON 整数字段的文本形式 | Go 类型解码,例如 1.0 不作为整数控制字段接受 |
|
||
| 当前会话、reply_to 与原操作匹配 | WS 会话及 SDK 控制请求表 |
|
||
| 身份、权限、队列、租约、版本及时间先后关系 | 数据库事务与执行状态机 |
|
||
| 原始回执与当前执行权分离 | CommandResult.receipt 与 lease;历史回执不能复活执行 |
|
||
|
||
通过 Schema 只说明报文形状合法,不能证明请求已获授权、操作已经提交或业务副作用只发生一次。
|
||
|
||
## 可复现的验证
|
||
|
||
```sh
|
||
go test -race ./internal/transport/httpserver -run TestWorkerPublishedContract
|
||
make integration
|
||
```
|
||
|
||
契约测试对合法消息及变异消息同时运行 Schema 和实际应用输入校验,包含数组内字段别名、缺少字段、错误方向、容量边界、计数溢出、非规范秘密及结果分类。真实 MySQL/WSS 测试在发送和接收时校验实际报文,并覆盖注册、容量、派发、开始、续租、恢复、结果及错误。
|
||
|
||
测试使用固定版本 [santhosh-tekuri/jsonschema v6.0.2](https://pkg.go.dev/github.com/santhosh-tekuri/jsonschema/v6@v6.0.2),显式开启 AssertFormat。这个验证器只用于测试工具包,不进入 Orbit 服务二进制或独立 SDK 的依赖图;运行平台仍只要求 MySQL。
|