modify: json 解析优化

This commit is contained in:
2026-08-22 03:53:31 +08:00
parent 440efa716f
commit 8b13ed17e6
9 changed files with 603 additions and 44 deletions
+27 -3
View File
@@ -81,6 +81,7 @@ chongming/routes/<type>/__meta__ # 插件级元信息(可选,仅在声
| `docstring` | string | `""` | OpenAPI 描述 |
| `timeout` | number | `3.0` | 单次调用超时(秒);流式端点为其**总寿命上限**,须配大(如 300) |
| `cacheable` | bool | `false` | 网关侧结果缓存开关(成功响应按 `(type, subject, payload)` 缓存) |
| `validate` | bool | `true` | 网关是否解析并校验请求体(false = 原样透传,校验下沉 worker;仅对 POST/PUT/PATCH 非流式端点生效,见 §4.2) |
| `auth_required` | bool | `true` | 网关是否注入鉴权依赖(认证用户经信封 `meta.user_info` 透传给插件) |
| `internal` | bool | `false` | 内部端点:不注册 HTTP 路由,仅保留 Zenoh RPC 调用能力 |
| `stream` | bool | `false` | 流式端点:网关以 SSE 逐块转发多回复 |
@@ -147,17 +148,33 @@ worker/<type>/<id>/<subject>
**兼容规则**:非信封载荷(不含 `meta`/`data` 键的 JSON 对象)整包视为业务 `data`,按 `method = GET` 处理。
**透传模式(`validate = false` 端点)**:`data` 为请求体的**原始 JSON 值**(网关零解析/校验,
信封由字节拼接构造,结构不变)。插件收到的 `data` 形态与校验模式一致(由 SDK 解析为 dict);
参数类型转换/校验失败由插件侧暴露(框架异常经 `reply_err` → 网关 503)。空/空白请求体兜底为 `{}`。
### 4.3 响应
| 形态 | 行为 |
| ---- | ---- |
| 普通 | 单个回复,载荷为业务结果 JSON 对象 |
| 异常(非流式) | 单个回复:`{"result": 0.0, "operation": "error", "error": "<异常信息>", "worker": "<worker_id>"}` |
| 流式 | 对同一 Query **多次 reply** 逐块推送;生成器正常结束 = 流结束(无结束哨兵);中途异常以 `{"error": "<异常信息>"}` **收尾块**结束流;查询已终止(客户端断开)时停止回复 |
| 框架异常(非流式) | 单个 **`reply_err`** 回复,载荷 `{"result": 0.0, "operation": "error", "error": "<异常信息>", "worker": "<worker_id>"}`;网关据此零解析判定失败 → 重试 → HTTP 503 |
| 业务错误 | 普通回复(如 `{"code": 1, "error": "..."}`),HTTP 200 透传,网关不解析 |
| 流式 | 对同一 Query **多次 reply** 逐块推送;生成器正常结束 = 流结束(无结束哨兵);中途异常以 `{"error": "<异常信息>"}` **收尾块**结束流(流式错误仍为普通回复,不走 `reply_err`);查询已终止(客户端断开)时停止回复 |
> **错误通道分层**:框架异常(handler 抛错、无匹配方法、超时)→ `reply_err`;
> 业务错误(业务逻辑判定失败)→ 普通回复。插件作者语义:**返回即业务、抛出即框架**。
>
> **兼容矩阵**(新旧网关/插件任意组合均语义完好):
>
> | 网关 \ 插件 | 旧(普通回复错误信封) | 新(reply_err) |
> | ----------- | ---------------------- | --------------- |
> | 旧 | HTTP 200 + 错误信封(历史行为) | `call()` 已处理 reply.err → 重试 → 503 |
> | 新 | HTTP 200 + 错误信封(透传不解析,业务语义) | reply_err → 重试 → **503**(语义修正) |
网关侧对应行为:
- 普通调用 `WorkerManager.call`:取首个回复;空回复 / zenoh 层错误 / 超时 → **切换副本重试**(默认重试 1 次)
- 普通调用 `WorkerManager.call_raw`(HTTP 端点):取首个回复,**原始字节零解析透传**给 HTTP 响应;空回复 / reply.err / 超时 → **切换副本重试**(默认重试 1 次),重试耗尽 → HTTP 503
- `call()`(MQTT Bridge 等内部调用方):同上述重试逻辑,回复解析为 dict 后使用
- 流式调用 `WorkerManager.call_stream`:逐块消费(`ConsolidationMode.NONE`);收到含 `error` 键的块视为终止信号转发后结束;`reply.err`(zenoh 层错误)同样终止流
- 无可用副本 → HTTP 503
@@ -204,6 +221,13 @@ worker/<type>/<id>/<subject>
- **协议变更分级**:
- 破坏性变更(keyexpr 结构、信封结构、错误格式、描述符语义)→ `schema_version` 递增,网关须先发布兼容处理,再切换
- 新增可选字段 / 新增端点形态 → 允许同版本内演进,但必须同步更新本规范
- **本版同版本内演进说明(2026-08)**:
- 新增描述符字段 `validate`(§2.2,网关缺失时兜底 true,纯增量)
- 非流式框架异常新增 `reply_err` 错误通道(§4.3):信封结构与错误载荷均不变,
仅输出通道由普通 reply 改为 reply_err;网关 `call()/call_raw()` 历史上已处理 reply.err,
新旧组合兼容(见 §4.3 兼容矩阵),故不递增 schema_version
- 网关普通调用由 `call`(dict 语义)切换为 `call_raw`(bytes 透传):入参出参形态变化
为网关内部实现,不影响线上协议
- **修改即更新**:任何实现侧改动(`routes_publisher.py` / `runtime.py` / `route_registry.py` / `worker_manager.py` / `route_generator.py`)触及本规范描述的语义时,必须同步修订本规范
---