modify: worker 管理端点

This commit is contained in:
2026-08-27 09:49:47 +08:00
parent 2270f2f6e8
commit 378128fc16
10 changed files with 967 additions and 143 deletions
@@ -0,0 +1,42 @@
# 修复 Worker 单副本重启 500:优雅处理「副本未响应管理指令」
## 摘要
单副本重启端点 `POST /api/v1/admin/workers/restart` 在目标 worker 不在线/无 `__admin__` 管理能力时,`_send_admin_cmd` 抛 `RuntimeError`,端点未捕获,被全局异常处理器记录后 re-raise,最终 ASGI 返回 500 并伴随 `net::ERR_FAILED`。需让该端点对「未响应/不在线/运行旧版」返回明确的非 500 结构化错误,同时改进错误文案以便运维定位。
## 现状分析
- [worker_admin.py](file:///home/chakcy/chongming-zenoh/src/chongming/app/routes/worker_admin.py#L60-L80):`restart_worker` 直接 `await manager.restart_worker(...)`,无 try/except。对比 `restart_all`(L107 已捕获单副本失败不中断)、`update_worker_config`(L169-178 已捕获映射 4xx),唯独单副本端点无兜底。
- [worker_manager.py](file:///home/chakcy/chongming-zenoh/src/chongming/app/core/worker_manager.py#L507-L553):`_send_admin_cmd` 在 Zenoh QUERY 超时/无回复时 `raise RuntimeError("副本 <type>/<id> 未响应管理指令(可能不在线)")`(L544-547)。
- [__init__.py](file:///home/chakcy/chongming-zenoh/src/chongming/app/__init__.py#L244-L255):全局处理器仅记录 `logger.error(f"全局异常: {exc}")` 后 re-raise → 500。
- 底层:报错实例 `worker_id=worker-0-52047` 是**旧版命名**(`worker-<index>-<pid>`,无 epoch 段)。新版 runtime 才生成 `worker-<index>-<epoch>-<pid>` 并声明 `__admin__`。故该副本极可能仍运行**旧版 chongming_worker**(未加载管理能力),管理层才会未响应。
## 变更方案
### 1. 单副本重启端点兜底 [worker_admin.py](file:///home/chakcy/chongming-zenoh/src/chongming/app/routes/worker_admin.py)
- 在 `restart_worker` 中 `try: result = await manager.restart_worker(...)`。
- `except Exception as e:`(noqa BLE001)→ `logger.warning(...)` 记录;若错误含「未响应/不在线」,抛 `HTTPException(status_code=502, detail=f"重启失败: {e}(该副本可能不在线或运行旧版 Worker,未加载管理能力,请先以新版重启其进程)")`;其余错误保持映射 502/500 语义(统一用 502 + detail=str(e) 即可)。
- 效果:不再触发全局异常 handler / ASGI 500;前端 `restartOne` 已在其 catch 中 `ElMessage.error` 展示 `detail`,用户得到明确提示。
### 2. 优化下发错误文案 [worker_manager.py](file:///home/chakcy/chongming-zenoh/src/chongming/app/core/worker_manager.py)
- 将 L545-547 的超时错误文案改为:
`"副本 {worker_type}/{worker_id} 未响应管理指令(可能不在线,或该 Worker 运行旧版运行时未声明 __admin__ 管理能力)"`
- 便于网关日志与前端 detail 直接反映根因。
### 3. 前端(可选,本次不强制改)
- `restartOne` 已能在非 2xx 时展示后端 `detail`,无需改动。仅确认错误提示文案来自后端 detail 即可。
## 假设与决策
- 「未响应」属**预期可解释的失败**,应返回 5xx(502)而非 200+ok:false:前端只对非 2xx 弹错,保持「消息清晰」。
- 不修改全局异常处理器:它是通用兜底,无需为此特化。
- 不修改 alive 判定/列表逻辑:`alive=true` 仅代表 liveliness token 存在,无法区分旧版进程;根因修复依赖「用新版 runtime 重启 worker 进程」,属运维动作,不写代码。
## 验证步骤
1. `.venv/bin/python -m py_compile src/chongming/app/routes/worker_admin.py src/chongming/app/core/worker_manager.py`。
2. 重启网关(让其加载 CORS 与最新代码)。
3. 用仍为旧版命名/未响应的 worker(如 `aibox_sophon_adapter/worker-0-52047`)调用 `POST /api/v1/admin/workers/restart?worker_type=aibox_sophon_adapter&worker_id=...`:
- 期望返回 JSON `{"detail":"重启失败: 副本 ... 未响应管理指令 ... 请先以新版重启其进程"}` 且 HTTP 502,不再打印「全局异常」,前端弹明确错误。
4. 对在线且加载新版 runtime 的 worker 重启,验证仍返回 `{"success":true}`(未破坏正常路径)。
5. `cd src/chongming-web && npx vue-tsc --noEmit`(如需改前端才跑;本次预计无前端改动)。
6. (可选)确认 Worker 管理重启按钮不再触发浏览器 `net::ERR_FAILED`,而是展示后端错误消息。
## 前置/运维提示(不写代码)
- 要让 `aibox_sophon_adapter` 等 external worker 能被单副本精细化管理(重启/停止/config_set),需用本项目最新 `chongming-worker`(`uv pip install -e utils/worker` 已确保)**重启该 worker 进程**,使其加载新版 runtime 并声明 `worker/<type>/<id>/__admin__`。