chongming-worker-rs —— 进程插件 Rust SDK
chongming 进程插件线协议(docs/plugin-wire-protocol.md)的 Rust 参考实现 (多语言演进规划阶段 1,见 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 |
插件开发三步
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):
# 项目根目录
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,杜绝模型与配置漂移。
// 插件内使用生成模型(强类型 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):
.venv/bin/python utils/worker-rs/scripts/zenoh_router.py &
协议级端到端验证(路由注册 / RPC / 流式 / 错误 / 摘除 / 自愈,15 项断言):
cargo build --examples
.venv/bin/python utils/worker-rs/scripts/verify_e2e.py --type rsdemo
Python + Rust 同 type 混布对拍(描述符 hash 一致 / 双副本发现 / RPC 等价 / 互不干扰):
.venv/bin/python utils/worker-rs/scripts/verify_mixed.py
参考插件(examples/demo.rs)支持两个 type:
# 项目根目录(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 |