修复 AGC Ctrl+C 残留上个工作树后端导致切换工作树复用旧后端
closes #314 新增 scripts/dev-windows-process.mjs:提供按根 PID 遍历与按身份匹配(api-server.exe 绝对路径、SpacetimeDB --data-dir)两条独立清理路径 scripts/dev.mjs:直接子进程(cmd.exe 包装层)已退出时仍按记录 PID 清理后代,不再提前 return scripts/dev.mjs:退出时按身份兜底清扫本工作树 api-server 与自建 SpacetimeDB,复用他人 standalone 时跳过 scripts/dev.mjs:启动前清理旧 api-server 保留 Wait-Process 等待语义,避免 cargo 报 failed to remove file apps/ai-game-creator-shell/scripts/start-dev-stack.mjs:复用配套后端前校验端口监听进程归属,无法证明归属则改为启动本工作树后端并允许端口漂移 apps/ai-game-creator-shell/scripts/start-dev-stack.mjs:收到信号与 finally 各兜底清扫一次本工作树 api-server.exe,taskkill 失败时降级为按 PID 遍历 apps/ai-game-creator-shell/scripts/start-dev-stack.mjs:等待后端就绪时输出归属校验未通过的具体原因,避免只表现为 600 秒超时 新增 scripts/dev-windows-process.test.ts 并扩充 AGC 复用门禁用例:覆盖断链遍历、身份匹配、归属判定与探测不可用退化 同步 docs/project-memory/shared-memory/pitfalls.md 与本地开发运维文档的进程清理与复用归属口径
This commit is contained in:
@@ -34,6 +34,18 @@
|
||||
|
||||
主配置与 local overlay 的单文件原子写入不能保证整体成功;覆盖层写入失败会留下混合配置。保存前先序列化全部变更,多文件保存保留原内容,错误时逆序恢复并报告回滚失败;单文件保持原写入路径,成功后不回读、不触发外部诊断。此回滚仅处理可捕获错误,不承诺进程崩溃下的事务恢复。
|
||||
|
||||
## 2026-09-09 `npm run agc` 的 Ctrl+C 不能只依赖 shell 包装层与端口健康检查
|
||||
|
||||
- **现象**:`npm run agc` 按 Ctrl+C 后终端回到提示符,但上个工作树的 `api-server.exe` / SpacetimeDB 仍在监听 `8082` / `8083` / `3101`;切到另一个 worktree 再启动 AGC 时,前端仍然连到上个工作树的后端,在改过数据库 / schema 的工作树上会串库。
|
||||
- **原因**:
|
||||
1. Windows 下所有长驻服务都由 Node `shell: true` 经 `cmd.exe /d /s /c` 包装层启动,Ctrl+C 会先杀掉包装层(退出码 `0xC000013A`)。`scripts/dev.mjs` 的 `stopProcess` 见到直接子进程已退出就直接 `return`,`start-dev-stack.mjs` / `start-tauri-dev.mjs` 对已退出 PID 的 `taskkill /PID <pid> /T /F` 只会失败并返回 `stopped: false`,于是更深的 `cargo → api-server.exe` 没有任何人收。
|
||||
2. 即使走到按根 PID 遍历进程树,遍历依赖快照里的父子链;中间层(包装层)先消失时链路断开,遍历只能拿到根 PID,深处的后端不可达。
|
||||
3. 复用判据只看 `.app/dev-stack.json` 的 status 与 `/healthz`、`/readyz`、`/v1/ping`,从不校验端口上的进程属于哪个工作树;残留后端照样“健康”,因此被当成自己的后端复用。
|
||||
- **处理**:新增 `scripts/dev-windows-process.mjs`,同时提供按根 PID 遍历与按身份匹配(`server-rs/target/debug/api-server.exe` 绝对路径、SpacetimeDB `--data-dir`)两条独立清理路径。`dev.mjs` 在直接子进程已退出时也继续清理,并在退出时按身份兜底清扫本工作树后端(复用他人 standalone 时不清理)。`start-dev-stack.mjs` 在收到信号和 `finally` 各清扫一次本工作树 `api-server.exe`(仅限本次自己拉起后端的情况),复用前先校验端口监听进程归属,无法证明归属就不复用、改为启动自己的后端并允许端口漂移。
|
||||
- **排查顺序**:先看 `.app/dev-stack.json` 的 status 与实际监听端口是否一致,再用 `Get-CimInstance Win32_Process` 按本工作树 `server-rs\target\debug\api-server.exe` 路径与 SpacetimeDB `--data-dir` 核对残留进程;不要因为 `/healthz` 返回 200 就认定后端属于当前工作树。
|
||||
- **验证**:`node --check scripts/dev.mjs scripts/dev-windows-process.mjs apps/ai-game-creator-shell/scripts/start-dev-stack.mjs`;`npx vitest run scripts/dev-windows-process.test.ts apps/ai-game-creator-shell/tests/start-dev-stack.test.ts scripts/dev.test.ts`;真机确认 Ctrl+C 后没有匹配本工作树 `api-server.exe` 路径的残留进程。
|
||||
- **关联**:`scripts/dev.mjs`、`scripts/dev-windows-process.mjs`、`apps/ai-game-creator-shell/scripts/start-dev-stack.mjs`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 2026-09-02 Tauri 事件桥在浏览器预览中必须 fail-safe
|
||||
|
||||
- **现象**:Vitest/jsdom 挂载 AGC 客户端时,错误报告通知调用 `@tauri-apps/api/event.listen`,因缺少 `window.__TAURI_INTERNALS__` 产生未处理拒绝;测试断言虽通过,CI 仍以 unhandled errors 失败。
|
||||
|
||||
Reference in New Issue
Block a user