fix(ios): stop charging every capture for a slow Simulator app discovery - #2331
Open
thymikee wants to merge 2 commits into
Open
fix(ios): stop charging every capture for a slow Simulator app discovery#2331thymikee wants to merge 2 commits into
thymikee wants to merge 2 commits into
Conversation
Since #2279 every eligible Simulator capture resolves its AX-bridge target first, and a cache miss spawns `simctl launchctl list` through xcrun with a 3s timeout on the capture's own critical path. On a loaded CI host that spawn takes longer than 3s, the timeout is not remembered, and the next capture pays it again. A `wait` issued right after `open` lost its whole 10s budget that way (runner findText on the fresh app, then the probe timeout, then a fallback capture cancelled at the deadline) and reported `wait_capture_stalled` with the app already on screen: four iOS Smoke failures on main and PRs since 2026-09-05 21:00, none before. Discovery is now single-flight and detached from the capture that starts it: a capture waits a bounded 1.5s for it, then takes the XCTest fallback while the probe keeps running with its own 15s budget; later captures join the in-flight probe or reuse its result. A responsive host still reaches the bridge on the first capture. The resolver's error names its reason so the route diagnostic says why the fallback ran.
Size Report
Startup median (7 runs, lower is better):
|
…ssion Review follow-up. The 15s budget was per subprocess (two simctl probes, then a 3s ps read); discovery now shares one deadline across all three. The comments and changelog no longer claim "once per app generation": single-flight removes duplicate discoveries, each capture still waits up to its 1.5s slice for the in-flight one, and a failed discovery is forgotten so the next capture starts another. A route-level test runs the production resolver over a simctl that answers only when released: the first capture falls back within the slice, the released discovery then serves the bridge without a second spawn.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes repeated concurrent app discovery on the iOS Simulator AX-bridge route and bounds how long each capture waits for it. Resolver and route regression tests pass; loaded-host smoke validation is what this PR's own CI run will show, and it was still pending when this was written.
The failure it targets
Since #2279 landed (09-05 21:06), the iOS Smoke lane has failed four times with one signature, the first
wait text "Agent Device Tester"after a coldopen --relaunchreportingwait_capture_stalledwithreadableCaptures: 0:80997b6b: https://github.com/callstack/agent-device/actions/runs/33992502696f30328d0: https://github.com/callstack/agent-device/actions/runs/34014253127fix/2314-memoize-platform-runtime-la: https://github.com/callstack/agent-device/actions/runs/34016148244The request log of the third run (artifact
ios-artifacts,sessions/ios-e2e-smoke-14ax/requests/45ad58af8fd6970d.ndjson) accounts for the 10s budget:findTexton the just-launched appxcrun simctl spawn … launchctl list,xcrun timed out after 3000msThe failed-step screenshot and snapshot the harness took right after (#2315) show the home screen rendered with a healthy tree. That is consistent with the timeline, not proof the app was readable throughout the wait.
createSimulatorSnapshotTargetResolver(snapshot-target.ts) ran that spawn with a fixed 3s timeout on every cache miss, on the capture's critical path, and kept nothing on timeout, so the next capture ran its own probe again while xcrun was slow. xcrun takes about 1s on an idle Mac with simulators booted; on these CI hosts it exceeded 3s in both captures of that run, and the same hosts time outsimctl terminateat 2s in other artifacts.Change
simulator-target-discovery-pending. Captures that keep arriving while the probe runs each wait up to that slice; the probe is shared, not repeated.psidentity read.ios_snapshot_route_fallbackdiagnostic says why the fallback ran.A responsive host still reaches the bridge on the first capture (local probe ≈ 1s < 1.5s).
What is verified
spawnmock, fake timers): slow discovery yields to the fallback and finishes in the background; concurrent captures join one discovery; a cancelled caller leaves it running; one deadline is shared by the probes and the identity read. The first three fail on the old code (hang, second spawn, second spawn).target-resolution-failedwarning, the released discovery then serves the bridge without a second spawn.wait for Agent Device Tester269ms, 23 captures served by the bridge,smoke:automation-inputgreen. This proves the healthy route, not the loaded-host case. (A laterkeyboard dismissfailure in that run is my local Simulator.app hardware-keyboard environment.)Not verified here
waitcompleting through the fallback: no local way to make xcrun slow; the lane's own runs are the evidence.waitloop.Relation to open work
#2329 changes
snapshot-route.ts(launch grace on typed bridge failures) and makeswaitobserve runner-free; it does not touch the probe, and its design needs the probe to be cheap on the critical path. #2325 coversopenstartup budgets. This PR does not change thewaitcontract.