Adds an opt-in dependency supervisor inside the Host Agent that probes,
spawns, and restarts the two local processes the macOS single-machine
real-device workflow depends on: the Appium server (gates Driver.connect())
and the local Runtime API (local inspection). Default-off; gated by
HOST_AGENT_DEPENDENCY_SUPERVISOR_ENABLED plus per-dependency *_SUPERVISED
flags.
Mitigates the live-incident failure mode where forgetting to start Appium
silently keeps devices offline and tasks queued forever with no error
surfaced in Host Agent logs.
Behavior (per openspec change):
- Adopt-don't-fight: probe (TCP + dependency-specific HTTP health check)
before spawn. Healthy listener → adopted (never killed/restarted).
Unhealthy listener → port-conflict error, skip. No listener → spawn.
- Only supervisor-spawned processes are restarted on crash, with capped
exponential backoff (1s/2s/4s/8s, capped at 30s) and a per-process-lifetime
attempt ceiling (HOST_AGENT_DEPENDENCY_RESTART_MAX_ATTEMPTS, default 5).
- Spawn failures (e.g. missing executable) logged distinctly from crashes.
- Graceful stop terminates only spawned children; adopted processes untouched.
- Supervisor starts before the heartbeat loop's first connect_devices() pass
and stops alongside existing heartbeat/console teardown.
Validation: ruff check + format clean, compileall clean, openspec validate
--strict valid. Non-integration suite 503 passed / 44 deselected / 2 failed
(both failures pre-existing from unrelated 03c7c30 LLM_PROVIDER_ENC_KEY;
verified by stashing this change). macOS real-device manual verification
(task 6.4) deferred to a macOS host.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -428,6 +428,61 @@ http://127.0.0.1:8765
|
||||
session TTL、历史记录条数上限等)参见 `docs/CLOUD_DEPLOYMENT.md`;生产/远程场景下
|
||||
应优先使用 SSH 端口转发访问该 Console,而不是直接把它暴露到非回环地址。
|
||||
|
||||
### 可选:由 Host Agent 托管 Appium 和 Runtime API
|
||||
|
||||
默认情况下 Host Agent **不会**自动启动 Appium 或本地 Runtime API:必须按
|
||||
§6 在独立 Terminal 中保持 `appium --address 127.0.0.1 --port 4723` 运行,按
|
||||
§8 在另一个 Terminal 中启动 Runtime API。忘记其中任意一个,Host Agent 不会报错,
|
||||
heartbeat 仍会成功,但设备会静默保持 `offline`、所有任务卡在 `queued`。
|
||||
|
||||
`host-agent-dependency-supervisor` 是一个可选模式,让 Host Agent 自己把这两个
|
||||
外部进程作为子进程托管,覆盖单机真机工作流。它默认关闭,需要显式 opt-in:
|
||||
|
||||
```bash
|
||||
export HOST_AGENT_DEPENDENCY_SUPERVISOR_ENABLED="true"
|
||||
|
||||
# 任选其一或两者都开。两者默认 false。
|
||||
export HOST_AGENT_APPIUM_SUPERVISED="true"
|
||||
export HOST_AGENT_RUNTIME_SUPERVISED="true"
|
||||
|
||||
# 可覆盖默认地址/端口(默认值与 §6/§8 手动流程一致):
|
||||
# export HOST_AGENT_APPIUM_HOST="127.0.0.1"
|
||||
# export HOST_AGENT_APPIUM_PORT="4723"
|
||||
# export HOST_AGENT_RUNTIME_HOST="127.0.0.1"
|
||||
# export HOST_AGENT_RUNTIME_PORT="8000"
|
||||
|
||||
# 单次 Host Agent 进程生命周期内允许的最大重启次数,默认 5。
|
||||
# export HOST_AGENT_DEPENDENCY_RESTART_MAX_ATTEMPTS="5"
|
||||
|
||||
uv run --package device-host-agent device-host-agent
|
||||
```
|
||||
|
||||
启用后的行为(详见 `openspec/changes/host-agent-dependency-supervisor/`):
|
||||
|
||||
- **启动顺序**:Host Agent 在第一次 `connect_devices()` 之前,先按上面选中的
|
||||
依赖项依次做"先探测后启动"。这样一旦开启,Appium 不再需要单独的 Terminal。
|
||||
- **Adopt-don't-fight**:探测 `(host, port)` 时若已经有进程在监听并通过健康检查
|
||||
(Appium `GET /status` 返回 200 JSON,Runtime `GET /devices` 返回 200 JSON),
|
||||
Host Agent 会以 *adopted* 方式记录日志,**不会**再 spawn 一个重复进程,也不会
|
||||
在退出/崩溃时杀掉或重启它。如果端口被占但健康检查失败,记一条 port-conflict
|
||||
错误并跳过该依赖,不抢端口、不静默继续。
|
||||
- **崩溃重启**:只有 Host Agent 自己 spawn 出来的子进程才会被监控。子进程意外
|
||||
退出时,按指数退避(1s、2s、4s、8s,封顶 30s)重启;当某个依赖在本进程生命
|
||||
周期内累计达到 `HOST_AGENT_DEPENDENCY_RESTART_MAX_ATTEMPTS` 次重启后,停止
|
||||
再次尝试直到 Host Agent 重启。被 adopt 的进程永远不会被 Host Agent 重启或杀死。
|
||||
- **spawn 失败 ≠ crash**:如果 `appium` 可执行文件不在 `PATH` 上,启动会以
|
||||
"dependency-supervisor: appium spawn failed — executable not found" 形式记一条
|
||||
依赖主管特有的错误,与正常 crash 区分开。请确认按 §4.3 安装好 `appium` 和
|
||||
XCUITest/UiAutomator2 driver。
|
||||
- **退出时**:Host Agent 在自身 graceful shutdown 阶段只会 `terminate` 它自己
|
||||
spawn 的子进程;adopted 进程保留不动。
|
||||
- **不影响 Docker/Compose**:本模式只针对 macOS 单机真机工作流;
|
||||
`compose.yaml` / `compose.deploy.yaml` 完全不受影响。
|
||||
|
||||
如果偏好保持对 Appium 终端日志的完全控制、或者已经在用其他进程管理工具
|
||||
(launchd、systemd、tmux 等)托管 Appium,可以继续使用 §6/§8 的手动流程,
|
||||
不开启本模式即可。
|
||||
|
||||
## 10. 多设备与端口
|
||||
|
||||
同时连接多台 iPhone 时,每台设备至少需要:
|
||||
|
||||
Reference in New Issue
Block a user