修复 AGC Ctrl+C 残留上个工作树后端导致切换工作树复用旧后端 #315
Reference in New Issue
Block a user
Delete Branch "fix/agc-ctrl-c-stale-backend"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
closes #314
现象
npm run agc按 Ctrl+C 后有概率残留上个工作树的api-server.exe/ SpacetimeDB,切换 worktree 再启动时 AGC 复用旧后端,改过数据库 / schema 的工作树会串库。根因
shell: true的cmd.exe /d /s /c包装层启动,Ctrl+C 先杀包装层(0xC000013A);dev.mjs的stopProcess见到直接子进程已退出就 return,taskkill /PID <已退出 PID> /T /F也只会失败,深处的cargo → api-server.exe无人清理。.app/dev-stack.jsonstatus 与/healthz、/readyz、/v1/ping,不校验端口上的进程属于哪个工作树,残留后端照样被判为健康并复用。改动
scripts/dev-windows-process.mjs:按根 PID 遍历 + 按身份匹配(server-rs/target/debug/api-server.exe绝对路径、SpacetimeDB--data-dir)两条独立清理路径,带 1s 快照缓存避免清理被拖慢。scripts/dev.mjs:直接子进程已退出时仍按记录 PID 清理后代;退出时按身份兜底清扫本工作树后端(复用他人 standalone 时跳过);启动前清理旧 api-server 保留Wait-Process语义,避免failed to remove file。apps/ai-game-creator-shell/scripts/start-dev-stack.mjs:复用前校验端口监听进程归属,无法证明归属就不复用、改为启动本工作树后端并允许端口漂移;信号与finally各兜底清扫一次;taskkill失败时降级按 PID 遍历;等待就绪时输出归属校验失败原因,避免静默超时。探测不可用时退化为旧行为,不阻断本地启动。scripts/dev-windows-process.test.ts、扩充 AGC 复用门禁用例;同步docs/project-memory/shared-memory/pitfalls.md与本地开发运维文档。验证
api-server.exe进程:按身份精确命中并杀掉(matched=[17284] stopped=[17284])。owned/api-server-owner-mismatch/spacetime-owner-mismatch均正确。npx vitest run scripts/dev.test.ts scripts/dev-windows-process.test.ts scripts/dev-stack-port-utils.test.ts apps/ai-game-creator-shell/tests/...:119 passed(唯一失败为 Windows 文件权限用例,已确认在合并基线origin/master上同样失败)。node --check、eslint --max-warnings 0、prettier --check、npm run check:encoding、git diff --check全部通过。备注
Rust 侧
api-server的with_graceful_shutdown没有超时上限,是「有概率」的来源之一;本次只在 Node 侧收口,是否给优雅退出加 deadline 可另行评估。