modify: 进程插进目录结构更新
This commit is contained in:
@@ -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
@@ -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> # 生成模型
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user