Files
2026-08-31 17:18:03 +08:00

127 lines
5.5 KiB
Markdown
Raw Permalink 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.
# chongming-worker-rs —— 进程插件 Rust SDK
chongming 进程插件线协议([docs/plugin-wire-protocol.md](../../docs/plugin-wire-protocol.md))的 **Rust 参考实现**
(多语言演进规划阶段 1,见 [docs/multi-language-plugin-plan.md](../../docs/multi-language-plugin-plan.md))。
与 Python SDK(`utils/worker/`)行为等价:同一 `<type>` 下可混布部署,网关负载均衡在
两实现间透明分发。**已通过协议级 15/15 与混布对拍 6/6 端到端验证。**
## 模块结构
| 模块 | 职责 | 对位(Python SDK) |
| ---- | ---- | ---- |
| `config.rs` | 全局 config.toml(`[zenoh].json5_path`)+ 插件 `[workers]` 节展平 + mqtt_topics | `process.py: load_plugin_config` |
| `descriptor.rs` | 端点 TOML 解析 → 路由描述符(defaults 合并 / subject / path / route_id) | `route_config.py` + `routes_publisher.py` |
| `envelope.rs` | 请求信封解析(meta.method / user_info / data,非信封载荷按 GET) | `runtime.py` |
| `error.rs` | 非流式错误格式 / 流式 error 收尾块 | `runtime.py` |
| `publisher.rs` | 描述符 PUT / DELETE / 10s 周期重发布 | `routes_publisher.py` |
| `serve.rs` | worker_serve 主流程:liveliness token + Queryable + 信号处理 | `process.py: worker_serve` |
## 插件开发三步
```rust
use chongming_worker_rs::prelude::*;
let mut registry = HandlerRegistry::new();
// 普通端点
registry.register("rsdemo.hello", "GET", |req: Request| async move {
Ok(Reply::Json(json!({"greeting": "Hello!"})))
});
// 流式端点(SSE 逐块)
registry.register("rsdemo.stream", "POST", |req: Request| async move {
let stream = async_stream::stream! {
for i in 0..5 { yield Ok(json!({"index": i})); }
};
Ok(Reply::Stream(Box::pin(stream)))
});
serve::serve("rsdemo", Arc::new(registry), ServeOptions::default()).await?;
```
端点 TOML 定义与 Python 插件共用同一套格式(`config/workers/<type>/*.toml`),
描述符生成规则逐字段对位(`docs/plugin-wire-protocol.md` §2.2)。
## 模型生成(TOML 是唯一事实来源)
请求/响应模型由端点 TOML 的 `params` / `response_model` 声明**自动生成**
(对齐 Python `gen_models`,命名约定一致:`hello` + `GET` → `HelloGetRequest`):
```bash
# 项目根目录
cargo run --bin gen_models -- --types rsdemo,demo --out utils/worker-rs/generated_models.rs
```
生成文件(crate 根 `generated_models.rs`,勿手动修改)每个插件类型一个 mod,
结构体带 serde derive,字段类型映射对齐网关(str/int/float/bool/any/list/dict)。
**一致性保证(比 Python 更强)**:生成文件头部写入 `FINGERPRINT`(端点 TOML 内容 hash)。
插件启动时(`check_models_fingerprint`)重算指纹比对——**TOML 变更而未重新生成模型
即告警并提示重跑 gen_models**,杜绝模型与配置漂移。
```rust
// 插件内使用生成模型(强类型 handler)
let req: generated_models::rsdemo::HelloGetRequest = serde_json::from_value(request.data)?;
let resp = generated_models::rsdemo::HelloGetResponse {
greeting: format!("Hello, {}!", req.name),
worker_id: Some(request.worker_id),
timestamp: now_ts(),
};
```
类型映射规则(对齐网关 `route_generator` 的 TYPE_MAP):
| TOML 声明 | Rust 类型 | 说明 |
| ---- | ---- | ---- |
| `str` | `String` | |
| `int` | `i64` | |
| `float` | `f64` | |
| `bool` | `bool` | |
| `any` | `serde_json::Value` | |
| `list[X]` / `List[X]` | `Vec<X>` | 递归映射 |
| `dict[K,V]` / `Dict[K,V]` | `HashMap<K,V>` | 递归映射 |
| 其他 | `serde_json::Value` | 宽松兜底 |
语义对齐:`params` 全部必填;`response_model` 中 `required = false` 的字段生成
`Option<T>` + `skip_serializing_if`(空值不输出)。
## 本地验证
前置:本地 Zenoh Router(替代 zenohd,`mode=router` 监听 7447):
```bash
.venv/bin/python utils/worker-rs/scripts/zenoh_router.py &
```
协议级端到端验证(路由注册 / RPC / 流式 / 错误 / 摘除 / 自愈,15 项断言):
```bash
cargo build --examples
.venv/bin/python utils/worker-rs/scripts/verify_e2e.py --type rsdemo
```
Python + Rust 同 type 混布对拍(描述符 hash 一致 / 双副本发现 / RPC 等价 / 互不干扰):
```bash
.venv/bin/python utils/worker-rs/scripts/verify_mixed.py
```
参考插件(`examples/demo.rs`)支持两个 type:
```bash
# 项目根目录(config.toml 相对路径)
utils/worker-rs/target/debug/examples/demo --type rsdemo # 独立演示插件
utils/worker-rs/target/debug/examples/demo --type demo # 与 Python demo 混布对拍
```
**独立插件形态**(插件开发者实际使用的方式):`workers/rsdemo/` 是一个完整独立的
插件 crate(path 依赖本 SDK),与 Python 示例 `workers/demo/` 对位,含端点实现、
生成模型与说明文档——建议新插件以此为模板。
## 与 Python SDK 的差异(有意为之)
| 差异 | 说明 |
| ---- | ---- |
| 契约校验 | Python 在 worker 进程内做 TOML↔注册表↔模型三方校验(硬失败退出);Rust 侧降级为**发布前自检**:无 handler 的端点告警并跳过,不发布残缺路由 |
| 模型生成 | Rust 有 gen_models 等价物(`--bin gen_models`):从端点 TOML 生成强类型结构体 + **启动时指纹校验**(TOML 变更未重生成即告警,比 Python 只查模型存在性更强) |
| handler 注入 | worker_id 经 `Request.worker_id` 注入(Python 为函数参数);user_info 经 `Request.user_info` |