478 lines
21 KiB
Markdown
478 lines
21 KiB
Markdown
# 进程插件开发指南(external 模式)
|
||
|
||
> 进程插件(Process Plugin)是运行在**独立进程**中的 Worker 插件(`load_mode = "external"`),
|
||
> 与网关零导入关系、仅经 Zenoh 通讯,可独立打包部署到不同容器。
|
||
> 本文档覆盖从**创建代码 → 配置 → 调试 → 验证 → 打包 → 部署**的完整开发流程。
|
||
|
||
---
|
||
|
||
## 1. 什么是进程插件
|
||
|
||
网关支持两种插件运行模式,**按插件粒度共存**(混合部署):
|
||
|
||
| 模式 | 运行位置 | 目录 | 路由来源 | 契约校验位置 |
|
||
| ---- | -------- | ---- | -------- | ------------ |
|
||
| **inline**(默认) | 网关进程内 import | `src/plugins/<name>/`(chongming-plugins 仓库) | 网关盘扫 TOML 生成 | 网关启动时 |
|
||
| **external(进程插件)** | 独立进程 | `workers/<name>/`(本地开发目录,**自包含项目**,不入库) | Worker 经 Zenoh 发布路由描述符,网关动态挂载 | **Worker 进程内** |
|
||
|
||
进程插件的特点:
|
||
|
||
- **零导入关系**:只依赖 `chongming-worker` SDK + zenoh,禁止 import `chongming`(网关包)
|
||
- **独立生命周期**:由 Docker/K8s 编排拉起,进程入口 `chongming-worker --type <name>`(SDK console script)
|
||
- **动态路由**:启动时把路由描述符发布到 Zenoh `chongming/routes/<type>/...`,网关 RouteRegistry 常驻订阅后动态挂载 HTTP 端点;退出时摘除
|
||
- **独立打包**:`uv run build_plugin <name>` 一键打包为可部署 zip,与网关分别部署到不同容器
|
||
- **代码结构一致**:与 inline 插件完全相同(Plugin 基类 + router/ + models/)
|
||
|
||
**适用场景**:需要独立扩缩容、强隔离(第三方依赖冲突、资源占用大)、或与网关发布节奏解耦的业务。
|
||
|
||
---
|
||
|
||
## 2. 工作机制(简述)
|
||
|
||
```mermaid
|
||
graph TB
|
||
HTTP[HTTP 客户端] -->|REST API| API[FastAPI 动态路由]
|
||
REG[网关 RouteRegistry<br/>订阅 chongming/routes/**] -->|动态挂载/摘除| API
|
||
API --> WM[WorkerManager<br/>负载均衡 + 超时重试]
|
||
|
||
subgraph GW[网关容器]
|
||
API
|
||
REG
|
||
WM
|
||
end
|
||
|
||
subgraph PW[进程插件容器 workers/demo]
|
||
WS[chongming-worker 进程]
|
||
WS -->|① put 路由描述符<br/>chongming/routes/demo/**| REG
|
||
WS -->|② liveliness 注册<br/>worker/demo/<id>| WM
|
||
end
|
||
|
||
WM -->|Zenoh Query| WS
|
||
WS -.->|每 10s 重发布(自愈)| REG
|
||
WS -.->|SIGTERM 时 delete 摘除| REG
|
||
```
|
||
|
||
`chongming-worker --type demo` 启动后的流程:
|
||
|
||
1. 读根 `config.toml` 的 `[zenoh]` 节打开会话,自读
|
||
`config/workers/demo/config.toml` 的 `[workers]` 节(含 `[workers.config]` 运行时配置)
|
||
2. import 插件模块触发 `@rpc_method` 注册 → **进程内契约校验**(不通过则退出码 1)
|
||
3. `create_workers` 创建副本(默认 `count` 个,`--count` 可覆盖),注册 liveliness
|
||
4. 经 Zenoh 把路由描述符 put 到 `chongming/routes/<type>/<route_id>`,网关动态挂载 HTTP 路由;
|
||
每 10s 重发布(网关后启动或样本丢失时自愈)
|
||
5. 收到 SIGTERM/SIGINT → delete 描述符(路由摘除)→ cleanup → 关闭会话
|
||
|
||
要点:网关容器**无需**放置 external 插件的配置文件(RouteRegistry 常驻订阅,与盘扫解耦);
|
||
描述符字段与 keyexpr 细节见 [线协议规范](plugin-wire-protocol.md)。
|
||
|
||
---
|
||
|
||
## 3. 目录结构约定
|
||
|
||
进程插件是**自包含项目**:`workers/<name>/` 即项目根,同时也是打包 zip 的根
|
||
(**gitignore,不入库**)。开发目录与容器工作目录完全一致,开发即产物:
|
||
|
||
```text
|
||
workers/<name>/ # 项目根 = zip 根 = 容器工作目录
|
||
├── workers/<name>/ # 插件代码(模块 workers.<name>)
|
||
│ ├── __init__.py # Plugin 子类 + create_workers / cleanup 模块级入口
|
||
│ ├── global_var.py # 模块级共享状态(Database、API client 等)
|
||
│ ├── router/ # RPC 端点实现
|
||
│ │ ├── __init__.py # 导入所有端点模块
|
||
│ │ └── <操作名>.py # 每个端点一个文件,@rpc_method 装饰器
|
||
│ ├── models/ # 数据模型(gen_models 自动生成,勿手动修改)
|
||
│ │ ├── __init__.py
|
||
│ │ └── pydantic.py # 请求/响应 Pydantic 模型
|
||
│ └── README.md # 插件说明(可选)
|
||
├── config/
|
||
│ ├── zenoh_config.json5 # Zenoh 会话配置
|
||
│ └── workers/<name>/ # 插件注册 + 端点配置
|
||
│ ├── config.toml # [workers] 节注册 + [worker] 元信息 + [workers.config]
|
||
│ └── <操作名>.toml # 每个端点一个定义文件
|
||
├── config.toml # 最小根配置(仅 [zenoh] 节,worker 启动必需)
|
||
├── pyproject.toml # uv 依赖清单(chongming-worker + 扩展依赖)
|
||
└── start.sh # 容器入口(uv sync + uv run chongming-worker --type <name>)
|
||
```
|
||
|
||
> 参考示例:`workers/demo/`(完整项目,含 5 个端点)。
|
||
|
||
---
|
||
|
||
## 4. 开发流程
|
||
|
||
### 第 1 步:生成项目骨架
|
||
|
||
```bash
|
||
uv run gen_plugin demo --process # 生成完整进程插件项目(含示例操作)
|
||
uv run gen_plugin demo hello storage --process # 指定初始操作
|
||
uv run gen_plugin demo add --process # 为已有项目增量添加操作
|
||
```
|
||
|
||
生成的代码位于 `workers/demo/workers/demo/`,其中 `__init__.py`(与 inline 插件
|
||
完全一致,推荐 Plugin 基类风格):
|
||
|
||
```python
|
||
import logging
|
||
|
||
from chongming_worker.plugin import Plugin
|
||
|
||
from . import router # noqa: F401 触发 @rpc_method 注册
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
class DemoPlugin(Plugin):
|
||
type = "demo"
|
||
db_name = None # 不需要数据库则置 None
|
||
auto_bind = True
|
||
|
||
async def on_init(self):
|
||
"""首次 create_workers 时调用一次:初始化资源。"""
|
||
# self.set_var("db", self.db)
|
||
pass
|
||
|
||
async def on_cleanup(self):
|
||
"""cleanup 时调用:关闭自定义客户端等。"""
|
||
|
||
|
||
_plugin = DemoPlugin()
|
||
create_workers = _plugin.create_workers
|
||
cleanup = _plugin.cleanup
|
||
```
|
||
|
||
> 注意:`module` 注册为 `workers.<name>` 时,`sys.path` 需包含项目根目录——
|
||
> `chongming-worker` 已自动处理(console script 启动时会显式把 CWD 加入 `sys.path`),
|
||
> 只需在项目根 `workers/<name>/` 下运行。
|
||
|
||
### 第 2 步:插件注册配置
|
||
|
||
创建 `workers/<name>/config/workers/<name>/config.toml`,`[workers]` 节注册插件
|
||
(**关键:`load_mode = "external"`**):
|
||
|
||
```toml
|
||
# workers/demo/config/workers/demo/config.toml
|
||
[workers]
|
||
type = "demo" # 插件类型(worker type)
|
||
module = "workers.demo" # Python 模块路径(进程插件用 workers.<name>)
|
||
factory = "create_workers" # 工厂函数名(Plugin 基类绑定的方法)
|
||
cleanup = "cleanup" # 清理函数名
|
||
count = 2 # Worker 副本数
|
||
load_mode = "external" # ★ 进程插件:独立进程运行,经 Zenoh 注册路由
|
||
|
||
[worker]
|
||
name = "demo"
|
||
version = "0.1.0"
|
||
description = "进程插件示例"
|
||
defaults = { method = "GET", timeout = 30.0, auth_required = false, cacheable = false, internal = false }
|
||
|
||
[worker.registration]
|
||
router_prefix = "/demo" # HTTP 路由前缀
|
||
tags = ["demo", "process-plugin"]
|
||
|
||
# Worker 运行时配置(展平后传给 create_workers 的 config 参数)
|
||
[workers.config]
|
||
greeting_prefix = "Hello"
|
||
```
|
||
|
||
> **运行时配置的来源(两种模式)**:`[workers.config]` 与 `count` 在启动时按
|
||
> `[workers.cache].launch_worker_count` 取值——`"toml"`(默认)以本文件为准,并把该段覆盖
|
||
> 写入共享缓存(网关 `GET /admin/workers/<type>/config` 读缓存,因此前端显示文件值);
|
||
> `"cache"` 以缓存为准(插件初始化即读缓存值,管理接口改动跨重启保持,本文件仅在缓存缺失时
|
||
> 引导)。进程插件未配置 `[workers.cache]` 时无缓存句柄,恒为 toml 语义,且与网关内同名
|
||
> 副本可能读到不同来源——需要与网关共享"改完即持久"的语义时请补上与网关一致的 `[workers.cache]`。
|
||
|
||
### 第 3 步:端点 TOML 定义
|
||
|
||
每个端点一个文件,如 `workers/<name>/config/workers/<name>/hello.toml`:
|
||
|
||
```toml
|
||
[GET]
|
||
summary = "进程插件示例:问候"
|
||
params = ["name: str"]
|
||
auth_required = false
|
||
|
||
[GET.response_model]
|
||
greeting = { type = "str", required = true }
|
||
worker_id = { type = "str", required = false, default = "" }
|
||
timestamp = { type = "float", required = true }
|
||
```
|
||
|
||
流式端点(SSE)在方法节追加 `stream = true` 并配大 `timeout`,详见主 README「流式端点」。
|
||
|
||
### 第 4 步:生成 Pydantic 模型
|
||
|
||
```bash
|
||
uv run gen_models workers/demo/config/workers/demo workers/demo/workers/demo
|
||
```
|
||
|
||
在 `workers/<name>/workers/<name>/models/` 下生成 `pydantic.py` 与 `__init__.py`。
|
||
|
||
### 第 5 步:实现 RPC 端点
|
||
|
||
`workers/<name>/workers/<name>/router/hello.py`:
|
||
|
||
```python
|
||
import time
|
||
|
||
from chongming_worker.decorators import rpc_method
|
||
|
||
from ..models.pydantic import HelloGetRequest, HelloGetResponse
|
||
|
||
|
||
@rpc_method(subject="demo.hello", method="GET", response_model=HelloGetResponse)
|
||
async def hello(request: HelloGetRequest) -> HelloGetResponse:
|
||
return HelloGetResponse(
|
||
greeting=f"Hello, {request.name}!",
|
||
timestamp=time.time(),
|
||
)
|
||
```
|
||
|
||
`workers/<name>/workers/<name>/router/__init__.py`:
|
||
|
||
```python
|
||
from . import hello
|
||
|
||
__all__ = ["hello"]
|
||
```
|
||
|
||
**异常语义**(插件作者只需 return / raise,通道由 SDK 处理):
|
||
|
||
| 形态 | 插件写法 | 网关行为 |
|
||
| ---- | -------- | -------- |
|
||
| 业务错误 | `return {"code": 1, "error": "..."}` | HTTP 200 透传(业务语义,网关不解析) |
|
||
| 框架异常(非流式) | `raise ValueError(...)` | SDK 经 `reply_err` 通道回复 → 网关重试后 **HTTP 503** |
|
||
| 流式异常 | 生成器内 raise | SDK 发送 `{"error": ...}` 收尾块 → SSE error 事件终止 |
|
||
|
||
即「**返回即业务、抛出即框架**」。注意:框架异常从历史行为「HTTP 200 + 错误信封」
|
||
修正为 **503**(`reply_err` 通道,见 wire 协议 §4.3 兼容矩阵)。
|
||
|
||
### 第 6 步:本地调试
|
||
|
||
在**插件项目根** `workers/<name>/` 下运行(worker 以 CWD 为工作目录读配置/import 代码):
|
||
|
||
```bash
|
||
cd workers/demo
|
||
uv sync # 首次:安装依赖(项目独立 venv,与容器一致)
|
||
uv run chongming-worker --type demo # 本地调试
|
||
uv run chongming-worker --type demo --count 1 # 覆盖副本数
|
||
./start.sh # 与容器一致的启动方式
|
||
# 开发期复用仓库 venv(已装好 SDK)时,用 --project 指向仓库根:
|
||
uv run --project .. chongming-worker --type demo
|
||
```
|
||
|
||
启动后预期日志:
|
||
|
||
```text
|
||
[demo] 路由发布完成: 5 端点 + 无元信息
|
||
[demo] Worker 进程就绪,等待退出信号...
|
||
```
|
||
|
||
> 若配置了 `load_mode` 非 `"external"`,会输出告警:网关也会在进程内加载该插件,
|
||
> 外部进程将与网关内副本**重复服务**。
|
||
|
||
### 第 7 步:联调验证
|
||
|
||
启动网关(`uv run serve`)后调用插件路由即可验证端到端:网关日志可见路由动态挂载,
|
||
worker 退出后路由自动摘除(请求变 404),重启 worker 后恢复。
|
||
|
||
### 第 8 步:打包
|
||
|
||
```bash
|
||
uv run build_plugin demo # → dist/demo.zip
|
||
uv run build_plugin demo --output /tmp/pkg # 指定输出目录
|
||
```
|
||
|
||
打包 = 项目根直接压缩(开发目录即产物,zip 根即容器工作目录),自动排除
|
||
`__pycache__` / `*.pyc` / `.venv` / `*.egg-info` / `.git`,`start.sh` 权限强制 0o755。
|
||
|
||
产物布局与 §3 完全一致(**zip 根即容器工作目录**):
|
||
|
||
```text
|
||
workers/<name>/ 插件代码(模块 workers.<name>)
|
||
config/workers/<name>/ 插件注册 + 端点配置
|
||
config/zenoh_config.json5 Zenoh 会话配置
|
||
config.toml 最小根配置(仅 [zenoh] 节,worker 启动必需)
|
||
pyproject.toml uv 依赖清单(chongming-worker 内网 git 源 + orjson + 扩展依赖)
|
||
start.sh 容器入口:uv sync --no-dev + uv run chongming-worker --type <name>
|
||
```
|
||
|
||
打包前校验(任一不满足即失败退出):
|
||
|
||
- `workers/<name>/` 项目根存在
|
||
- `workers/<name>/config/workers/<name>/config.toml` 存在且含 `[workers]` 节
|
||
- `workers/<name>/config/zenoh_config.json5` 与 `workers/<name>/config.toml`(含 `[zenoh]`)存在
|
||
- `load_mode` 非 `"external"` 时**告警**(不阻断,但会造成重复服务)
|
||
|
||
扩展依赖:直接在项目根 `pyproject.toml` 的 `dependencies` 中追加(如 `"minio"`)。
|
||
|
||
### 第 9 步:容器部署
|
||
|
||
```bash
|
||
# 镜像需预装 uv(https://docs.astral.sh/uv/)
|
||
unzip demo.zip -d /app
|
||
cd /app
|
||
./start.sh
|
||
```
|
||
|
||
- `start.sh` 自动执行 `uv sync --no-dev`(按 pyproject 从内网 git 源拉取 chongming-worker)并启动 worker
|
||
- 生产部署时进程插件与网关**分别打包到不同容器**:
|
||
- 网关容器:`chongming` + 依赖
|
||
- 进程插件容器:插件代码 + `chongming-worker` + 依赖
|
||
- 插件配置随 zip 部署在**插件容器**(worker 自读);网关侧无需放置
|
||
(RouteRegistry 常驻订阅 Zenoh 路由描述符,与盘扫解耦)
|
||
|
||
---
|
||
|
||
## 5. 文件传输:直连 S3/Minio 对象存储(不依赖网关)
|
||
|
||
进程插件可直接对接 S3/Minio 对象存储做文件传输——上传、下载、删除、预签名 URL
|
||
均由**插件自己的配置**(`[workers.config.storage]`)驱动,**数据路径不经过网关**
|
||
(预签名 URL 模式下网关甚至不参与数据传输:设备/浏览器拿到 URL 后直传/直取 Minio)。
|
||
|
||
### 5.1 配置
|
||
|
||
```toml
|
||
# workers/<name>/config/workers/<name>/config.toml
|
||
[workers.config.storage]
|
||
endpoint = "192.168.1.10:9000" # Minio 地址 host:port(不带协议前缀)
|
||
access_key = "minioadmin"
|
||
secret_key = "minioadmin"
|
||
bucket = "chongming-files"
|
||
secure = false # false=http(默认),true=https
|
||
region = "" # 可选
|
||
auto_create_bucket = true # 可选,默认 true:启动时确保 bucket 存在
|
||
```
|
||
|
||
语义(`chongming_worker.storage.StorageClient.from_config`):
|
||
|
||
| 情形 | 行为 |
|
||
| ---- | ---- |
|
||
| 未配置 / `enabled = false` | 存储关闭(`self.storage = None`),端点自行降级 |
|
||
| 配置段存在但缺必填键(endpoint/access_key/secret_key/bucket) | **启动硬失败**(ValueError),快速反馈配置错误 |
|
||
| 连接失败 / bucket 不可用 | 告警降级为 None(不影响其他端点) |
|
||
|
||
### 5.2 SDK 用法
|
||
|
||
基类在 `_bootstrap` 阶段检测到 `config["storage"]` 段即自动初始化
|
||
`self.storage`(无需任何额外代码);插件在 `on_init` 发布到 global_var 供路由读取:
|
||
|
||
```python
|
||
class DemoPlugin(Plugin):
|
||
async def on_init(self):
|
||
if self.storage is not None: # 配置了 storage 段才初始化
|
||
self.set_var("storage", self.storage)
|
||
```
|
||
|
||
路由内使用(同步核心 + async 包装,RPC handler 直接 await):
|
||
|
||
```python
|
||
from ..global_var import require
|
||
|
||
storage = require("storage")
|
||
await storage.aput_bytes("dir/file.txt", data) # 上传字节
|
||
await storage.aput_file("dir/file.txt", "/tmp/a.txt") # 上传本地文件
|
||
data = await storage.aget_bytes("dir/file.txt") # 下载字节
|
||
await storage.aget_file("dir/file.txt", "/tmp/b.txt") # 下载到本地文件
|
||
url = await storage.apresigned_put_url("dir/file.txt") # 预签名 PUT(设备直传)
|
||
url = await storage.apresigned_get_url("dir/file.txt") # 预签名 GET(设备直取)
|
||
await storage.adelete("dir/file.txt") # 删除
|
||
```
|
||
|
||
API 一览(`chongming_worker.storage.StorageClient`):
|
||
|
||
| 方法(async 同名加 `a` 前缀) | 说明 |
|
||
| ---- | ---- |
|
||
| `put_file(object_key, local_path, content_type=None)` | 上传本地文件(fput_object) |
|
||
| `put_bytes(object_key, data, content_type=None)` | 上传内存字节 |
|
||
| `get_file(object_key, local_path)` | 下载到本地文件 |
|
||
| `get_bytes(object_key)` | 下载为字节 |
|
||
| `delete(object_key)` | 删除对象 |
|
||
| `presigned_put_url(object_key, expires=3600)` | 预签名 PUT URL(默认 1 小时) |
|
||
| `presigned_get_url(object_key, expires=3600)` | 预签名 GET URL(默认 1 小时) |
|
||
|
||
### 5.3 参考示例
|
||
|
||
`workers/demo` 演示了 4 个文件传输端点(项目内 `config/workers/demo/` 下对应 TOML):
|
||
|
||
- `POST /demo/presign_upload` — filename → object_key + 预签名 PUT URL(设备直传)
|
||
- `GET /demo/presign_download` — object_key → 预签名 GET URL(设备直取)
|
||
- `POST /demo/upload_bytes` — base64 小文件经 Zenoh RPC 上传(大文件请用预签名直传)
|
||
- `GET /demo/download_bytes` — base64 小文件经 Zenoh RPC 下载
|
||
|
||
配置后重启 worker 即可用;未配置时这些端点返回「storage 未配置」错误(降级演示)。
|
||
|
||
> 依赖:minio SDK 随 `chongming-worker` 一起安装(utils/worker pyproject 已声明),
|
||
> 进程插件无需额外依赖。SDK 侧 `chongming_worker.storage` 不依赖网关包,
|
||
> 隔离性约束与打包流程均不受影响。
|
||
|
||
---
|
||
|
||
## 6. 隔离性约束
|
||
|
||
进程插件**禁止 import `chongming`(网关包)**,只允许依赖:
|
||
|
||
- `chongming-worker`(worker SDK:`chongming_worker.*`)
|
||
- `zenoh` / `pydantic` 等第三方库
|
||
- 插件自身的扩展依赖(项目根 `pyproject.toml` 中声明)
|
||
|
||
隔离性由框架保证:SDK 导入链路中一旦出现 `chongming` / `chongming.*` 的 import,
|
||
运行时立即 `ImportError`(启动即暴露),无需等到部署阶段。
|
||
|
||
---
|
||
|
||
## 7. 进程内契约校验
|
||
|
||
Worker 进程启动时自读 TOML 并**在自己进程内**做三方一致性校验
|
||
(`chongming_worker.contracts.validate_worker_contracts`),校验失败直接退出:
|
||
|
||
| 检查项 | 策略 |
|
||
| ---------------------------- | --------------- |
|
||
| TOML HTTP 路由缺 `@rpc_method` | **硬失败,进程退出** |
|
||
| `[MQTT]` / `internal` 路由缺注册 | 警告日志 |
|
||
| 已注册方法无 TOML 路由 | 警告日志(反向漂移检测) |
|
||
| params/response_model 缺生成模型 | 警告日志(gen_models 过期) |
|
||
| 生成模型未被任何路由引用 | 警告日志(孤儿模型) |
|
||
|
||
---
|
||
|
||
## 8. 常见问题排查
|
||
|
||
| 现象 | 原因 / 处理 |
|
||
| ---- | ----------- |
|
||
| 启动告警「load_mode 不是 external」 | 进程插件必须在 `workers/<name>/config/workers/<name>/config.toml` `[workers]` 节设置 `load_mode = "external"`,否则网关内副本与外部进程重复服务 |
|
||
| 契约校验失败、进程退出 | 检查 TOML 端点(subject/方法节)与 `@rpc_method(subject=..., method=...)` 是否一致;模型缺失时重跑 `uv run gen_models workers/<name>/config/workers/<name> workers/<name>/workers/<name>` |
|
||
| `TypeError: rpc_method() got an unexpected keyword argument 'stream'` | venv 里是旧版 chongming-worker(git 源拉取),本地未 push 的框架改动不生效;联调时 `uv pip install -e utils/worker` |
|
||
| 路由没出现 | worker 是否就绪(日志「路由发布完成」);网关 RouteRegistry 是否订阅(启动流程 5.1);每 10s 自愈重发布,稍等或重启 worker |
|
||
| 路由一直 404 | worker 是否已退出(优雅退出会摘除路由);进程被 SIGKILL 时描述符残留,重启 worker 后重发布自愈覆盖 |
|
||
| 找不到插件配置 | `chongming-worker` 须在**插件项目根** `workers/<name>/` 下运行(读 `config/workers/<name>/config.toml`,`--config` 可指定全局配置路径) |
|
||
| storage.* 端点报「storage 未配置」 | 插件 config.toml 未配置 `[workers.config.storage]`(或 `enabled = false` / 连接失败降级)。补齐配置后重启 worker;启动日志可见「对象存储已就绪」或「storage 连接失败」告警 |
|
||
| 容器内 import `workers.demo` 失败 | 确认在容器工作目录(zip 根)启动,`start.sh` 内含 `cd "$(dirname "$0")"`,启动入口会把 CWD 加入 sys.path |
|
||
|
||
---
|
||
|
||
## 9. 相关命令速查
|
||
|
||
```bash
|
||
uv run gen_plugin <name> --process # 生成进程插件项目骨架
|
||
cd workers/<name> # 以下均在插件项目根下执行
|
||
uv run chongming-worker --type <name> # 本地调试独立 Worker 进程(项目根下)
|
||
./start.sh # 与容器一致的启动方式(uv sync + 启动)
|
||
cd .. && uv run build_plugin <name> # 进程插件打包 → dist/<name>.zip
|
||
uv run gen_models workers/<name>/config/workers/<name> workers/<name>/workers/<name> # 生成模型
|
||
```
|
||
|
||
---
|
||
|
||
## 10. 参考
|
||
|
||
- [主 README:进程插件与混合部署](../README.md)
|
||
- [Worker 插件开发指南(inline,结构约定与装饰器细节)](../src/plugins/README.md)
|
||
- [Worker 框架(chongming-worker)](../utils/worker/README.md)
|
||
- [Worker 框架(Rust:chongming-worker-rs,多语言参考实现)](../utils/worker-rs/README.md)
|
||
- [chongming-cli(build_plugin / gen_models 等命令)](../utils/cli/README.md)
|
||
- [进程插件线协议规范(语言无关)](./plugin-wire-protocol.md)——网关与插件的唯一契约,其他语言实现(Rust/Go 等)据此开发
|
||
- [多语言插件演进统一规划(Rust 优先)](./multi-language-plugin-plan.md)
|
||
- 代码:`utils/worker/src/chongming_worker/process.py`(进程入口)、
|
||
`routes_publisher.py`(路由发布协议)、`contracts.py`(契约校验)、
|
||
`utils/cli/src/chongming_cli/build_plugin.py`(打包器)
|