feat(host-agent): add single-instance lock to prevent duplicate-process dispatch races
Acquire an exclusive, non-blocking filelock on the identity state directory as the first action of create_application(), before resolve_host_identity() or any enrollment/heartbeat side effect. A second process against the same identity_path exits immediately with InstanceAlreadyRunningError naming the lock path; the lock releases automatically on any process exit (including SIGKILL) via OS-level advisory locking, and explicitly during run_async()'s shutdown finally block. filelock is promoted from transitive to direct dependency (version unchanged at 3.29.7). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -404,6 +404,24 @@ Host Agent 会在本机回环地址提供 Console。必须保留并保护 `tasks
|
||||
直接注册意味着任何能访问该云端地址的设备都能自行注册成为 Host,没有审批环节,
|
||||
也没有限流保护;这一取舍依赖网络边界(防火墙/反向代理)而非应用层限制。
|
||||
|
||||
### 重复实例保护
|
||||
|
||||
Host Agent 启动时会先尝试获取一个独占的本地文件锁(位于
|
||||
`tasks/host_agent.lock`,与 `host_identity.json` 同目录),确保同一个 identity
|
||||
状态目录下同一时刻只有一个 Host Agent 进程在运行。这是为了避免两个进程用同一个
|
||||
`host_id` 同时心跳和 claim,导致任务派发落到从未注册过该设备的进程上(典型的
|
||||
`DeviceNotFoundError` 事故场景)。
|
||||
|
||||
如果启动时锁已被另一个仍在运行的进程持有,Host Agent 会立即以非零退出码退出,
|
||||
stderr 打印 `error: another Host Agent instance is already running ...`,**不会**
|
||||
联系云端、不会触发任何 enrollment。处理方式:
|
||||
|
||||
1. 用 `lsof tasks/host_agent.lock`(macOS)/ 任务管理器(Windows)或
|
||||
`pgrep -fa device-host-agent` 找到仍在运行的旧进程。
|
||||
2. 确认旧进程应被停止后,再 `kill` 它(或等它的 graceful shutdown 完成)。
|
||||
3. 重新启动 Host Agent。崩溃/被 `kill -9` 的旧进程退出时 OS 会自动释放文件锁,
|
||||
不需要手动删除 `host_agent.lock`。
|
||||
|
||||
### 使用本地 Web Console
|
||||
|
||||
Host Agent 启动时会同时启动本地 Web Console,用于在这台 Mac 上直接查看和管理
|
||||
|
||||
Reference in New Issue
Block a user