modify: 进程插进目录结构更新

This commit is contained in:
2026-08-26 09:37:31 +08:00
parent 741d7cda09
commit 2270f2f6e8
4 changed files with 28 additions and 25 deletions
+7 -7
View File
@@ -383,8 +383,8 @@ load_mode = "external" # 独立进程运行,经 Zenoh 注册路由
```bash
cd workers/demo
uv run worker_serve --type demo # 本地调试(首次先 uv sync 装依赖)
./start.sh # 与容器一致的启动方式(uv sync + 启动)
uv run chongming-worker --type demo # 本地调试(首次先 uv sync 装依赖)
./start.sh # 与容器一致的启动方式(uv sync + 启动)
```
- 生产部署:进程插件与网关**分别打包到不同容器**
@@ -410,7 +410,7 @@ config/workers/<name>/ 插件注册 + 端点配置
config/zenoh_config.json5 Zenoh 会话配置
config.toml 最小根配置(仅 [zenoh] 节,worker 启动必需)
pyproject.toml uv 依赖清单(chongming-worker 内网 git 源)
start.sh 容器入口:uv sync + worker_serve --type <name>
start.sh 容器入口:uv sync + chongming-worker --type <name>
```
- 打包自动排除 `__pycache__` / `*.pyc` / `.venv` 等,`start.sh` 权限强制 0o755
@@ -554,8 +554,8 @@ uv run serve # 启动开发服务
uv run gen_plugin <name> # 生成统一风格插件骨架
uv run gen_models # 生成 Pydantic 模型
uv run build # 构建打包(PyInstaller/Nuitka)
uv run worker_serve --type <name> # 独立 Worker 进程(本地调试,load_mode=external)
chongming-worker --type <name> # 独立 Worker 进程(容器入口)
uv run chongming-worker --type <name> # 独立 Worker 进程(项目根下本地调试,load_mode=external)
chongming-worker --type <name> # 独立 Worker 进程(容器入口)
uv pip install -e utils/<name> # 安装/更新工具包
```
@@ -594,7 +594,7 @@ uv pip install -e utils/<name> # 安装/更新工具包
- **插件加载模式**:按插件粒度声明在 `config/workers/<name>/config.toml` 的 `[workers]` 节
- `load_mode = "inline"`(默认):插件在网关进程内加载
- `load_mode = "external"`:插件以独立进程运行(进程编排交给 Docker/K8s,
进程入口 `uv run worker_serve --type <name>`),经 Zenoh 在 `chongming/routes/**`
进程入口 `uv run chongming-worker --type <name>`),经 Zenoh 在 `chongming/routes/**`
注册路由,网关动态挂载 HTTP 端点(RouteRegistry 常驻订阅,无需在网关侧保留插件配置)
- 两种模式可同时存在(混合部署)
- **进程插件与网关完全隔离**:进程插件只依赖 `chongming-worker` SDK + zenoh,
@@ -603,7 +603,7 @@ uv pip install -e utils/<name> # 安装/更新工具包
**生产部署时进程插件与网关分别打包到不同容器**:
- 网关容器:`chongming`(含 `src/chongming/`)+ 依赖
- 进程插件容器:插件代码(`workers/<name>/`)+ `chongming-worker` + 依赖,
入口 `chongming-worker --type <name>`(或 `uv run worker_serve --type <name>`),
入口 `chongming-worker --type <name>`),
打包: `uv run build_plugin <name>` → `dist/<name>.zip`(见「进程插件打包」)
- **Zenoh 配置**:`config/zenoh_config.json5`
- **插件注册**:`config/workers/<name>/config.toml` 的 `[workers]` 节,定义加载方式、副本数与运行时配置(旧全局 `config/workers/config.toml` 仅作兜底兼容)
+11 -11
View File
@@ -18,7 +18,7 @@
进程插件的特点:
- **零导入关系**:只依赖 `chongming-worker` SDK + zenoh,禁止 import `chongming`(网关包)
- **独立生命周期**:由 Docker/K8s 编排拉起,进程入口 `worker_serve --type <name>`(或 `chongming-worker --type <name>`)
- **独立生命周期**:由 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/)
@@ -44,7 +44,7 @@ graph TB
end
subgraph PW[进程插件容器 workers/demo]
WS[worker_serve 进程]
WS[chongming-worker 进程]
WS -->|① put 路由描述符<br/>chongming/routes/demo/**| REG
WS -->|② liveliness 注册<br/>worker/demo/<id>| WM
end
@@ -57,7 +57,7 @@ graph TB
### 2.2 Worker 进程启动流程(`chongming_worker.process.worker_serve`)
```text
worker_serve --type demo
chongming-worker --type demo
1. 读全局 config.toml(仅 [zenoh] 节)→ 打开 Zenoh 会话
2. 自读 config/workers/demo/config.toml 的 [workers] 节(load_plugin_config 展平)
3. import 插件模块(plugins.<name> / workers.<name>)→ 触发 @rpc_method 注册
@@ -111,7 +111,7 @@ workers/<name>/ # 项目根 = zip 根 = 容器工作目录
│ └── <操作名>.toml # 每个端点一个定义文件
├── config.toml # 最小根配置(仅 [zenoh] 节,worker 启动必需)
├── pyproject.toml # uv 依赖清单(chongming-worker + 扩展依赖)
└── start.sh # 容器入口(uv sync + uv run worker_serve --type <name>)
└── start.sh # 容器入口(uv sync + uv run chongming-worker --type <name>)
```
> 参考示例:`workers/demo/`(完整项目,含 5 个端点,配合 `test_worker_isolation.py` /
@@ -162,7 +162,7 @@ cleanup = _plugin.cleanup
```
> 注意:`module` 注册为 `workers.<name>` 时,`sys.path` 需包含项目根目录——
> `worker_serve` 已自动处理(console script 启动时会显式把 CWD 加入 `sys.path`),
> `chongming-worker` 已自动处理(console script 启动时会显式把 CWD 加入 `sys.path`),
> 只需在项目根 `workers/<name>/` 下运行。
### 第 2 步:插件注册配置
@@ -267,11 +267,11 @@ __all__ = ["hello"]
```bash
cd workers/demo
uv sync # 首次:安装依赖(项目独立 venv,与容器一致)
uv run worker_serve --type demo # 本地调试
uv run worker_serve --type demo --count 1 # 覆盖副本数
uv run chongming-worker --type demo # 本地调试
uv run chongming-worker --type demo --count 1 # 覆盖副本数
./start.sh # 与容器一致的启动方式
# 开发期复用仓库 venv(已装好 SDK)时,用 --project 指向仓库根:
uv run --project .. worker_serve --type demo
uv run --project .. chongming-worker --type demo
```
启动后预期日志:
@@ -313,7 +313,7 @@ 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 worker_serve --type <name>
start.sh 容器入口:uv sync --no-dev + uv run chongming-worker --type <name>
```
打包前校验(任一不满足即失败退出):
@@ -467,7 +467,7 @@ Worker 进程启动时自读 TOML 并**在自己进程内**做三方一致性校
| `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 后重发布自愈覆盖 |
| 找不到插件配置 | `worker_serve` 须在**插件项目根** `workers/<name>/` 下运行(读 `config/workers/<name>/config.toml`,`--config` 可指定全局配置路径) |
| 找不到插件配置 | `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")"`,worker_serve 会把 CWD 加入 sys.path |
@@ -478,7 +478,7 @@ Worker 进程启动时自读 TOML 并**在自己进程内**做三方一致性校
```bash
uv run gen_plugin <name> --process # 生成进程插件项目骨架
cd workers/<name> # 以下均在插件项目根下执行
uv run worker_serve --type <name> # 本地调试独立 Worker 进程
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> # 生成模型
+6 -4
View File
@@ -57,23 +57,25 @@ with zipfile.ZipFile(zip_path) as z:
"secret_key" not in z.read("config.toml").decode(),
)
# 依赖清单:chongming-worker 内网 git 源 + worker_serve 入口
# 依赖清单:chongming-worker 内网 git 源(worker 入口脚本由 SDK 提供,插件自身不声明)
pyproject = tomllib.loads(z.read("pyproject.toml").decode())
deps = pyproject["project"]["dependencies"]
check("pyproject 依赖包含 chongming-worker", "chongming-worker" in deps)
check("pyproject 依赖包含 orjson(SDK 运行时依赖)", "orjson" in deps)
check(
"pyproject 声明 worker_serve 入口",
pyproject["project"]["scripts"].get("worker_serve") == "chongming_worker.process:worker_serve",
"pyproject 不声明 project.scripts(非打包项目 uv 会跳过入口点)",
"scripts" not in pyproject.get("project", {}),
str(pyproject.get("project", {}).keys()),
)
check(
"pyproject 声明 chongming-worker git 源",
pyproject["tool"]["uv"]["sources"]["chongming-worker"]["git"] == gp.CHONGMING_WORKER_GIT,
)
# start.sh:可执行 + 指向正确的插件 type
# start.sh:可执行 + 用 SDK 的 chongming-worker 脚本启动正确的插件 type
start_sh = z.read("start.sh").decode()
check("start.sh 以 --type demo 启动", "--type demo" in start_sh)
check("start.sh 使用 chongming-worker(SDK console script)", "chongming-worker" in start_sh)
perms = (z.getinfo("start.sh").external_attr >> 16) & 0o777
check("start.sh 可执行(0o755)", perms == 0o755, oct(perms))
+4 -3
View File
@@ -25,10 +25,11 @@ POLL_TIMEOUT = 30.0
REPO = Path(__file__).parent.parent
PROJECT = REPO / "workers" / "demo"
# 优先使用仓库 venv 控制台脚本(避免在插件项目内新建 venv),否则退回 uv run --project
_WORKER_CMD = [str(Path(sys.executable).parent / "worker_serve"), "--type", "demo"]
# 优先使用仓库 venv 的 chongming-worker 控制台脚本(避免在插件项目内新建 venv),
# 否则退回 uv run --project(SDK 入口脚本,与容器 start.sh 一致)
_WORKER_CMD = [str(Path(sys.executable).parent / "chongming-worker"), "--type", "demo"]
if not Path(_WORKER_CMD[0]).exists():
_WORKER_CMD = ["uv", "run", "--project", str(REPO), "worker_serve", "--type", "demo"]
_WORKER_CMD = ["uv", "run", "--project", str(REPO), "chongming-worker", "--type", "demo"]
PASS = 0
FAIL = 0