fix: skip the redundant simulator list after a boot this run performed - #272
Merged
Conversation
janicduplessis
force-pushed
the
fix/skip-redundant-sim-list
branch
from
September 3, 2026 01:01
ab53287 to
5a06635
Compare
janicduplessis
marked this pull request as ready for review
September 3, 2026 06:18
janicduplessis
force-pushed
the
fix/skip-redundant-sim-list
branch
from
September 3, 2026 06:24
5a06635 to
816c135
Compare
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.
Description
On a run that creates a simulator,
ensureOwnedIosDeviceboots it with a blockingsimctl bootstatus -band thenensureIosBootedopens withresolveOwnedIosSim(udid)->listAllIosSims()->xcrun simctl list devices --json, purely to learn a state it already knows. The sim isBooted, so the function returns on the next line -- but that list is the first simctl call after a boot, and CoreSimulator is still busy for several seconds afterbootstatusclaims the boot is done. Measured on this machine:simctl list devices --jsoncosts 7.9 s right after a boot versus 0.06 s on a quiet one, and thedevice ... bootedphase line reported 12.3 s / 8.7 s / 2.0 s across the three cache-hit baselines ininvestigations/2026-09-02-cache-hit-run-time.md(mean total 72.6 s).Ownership is not weakened:
ensureOwnedIosDevicealready re-resolved the sim by name (resolveOwnedIosSim, orcreateOwnedIosSimfor one it just made) earlier in the same call chain, so invariant 2 is satisfied before anything boots.Solution
ensureOwnedIosDevicenow reports the udid it booted on the record it returns (bootedUdid), andensureIosBootedreturns{ ok: true, udid }immediately when that udid is the one it was asked about. It is deliberately narrow: the field is set only where this call actually ranbootIosSim-- the created path and the reuse path that found the sim shut down. A reused sim that was alreadyBootedcarries nobootedUdid, so it is still listed, because nothing in this process proves it did not shut down in between. AbootedUdidfor a different sim does not vouch for this one either.bootedUdidis attached afterconfigureOwnedIosSimhas written the registry, alongsidecreated/deviceType/runtime, so it is never persisted -- it means "this process booted it", and it would be a lie in the next one.I used the udid rather than the whole
IosSimRecordthe issue suggests: on the created path there is noIosSimRecordto return (createOwnedIosSimreturns a name and a udid, not asimctl listrow), and the udid match is the entire decision.No tool call changes, so invariant 9 needs nothing new here; the argument lists are untouched and one
simctl list devices --jsonis simply not issued.Test plan
engine-device.test.ts:ensureBootedissues zero commands when the record carries a matchingbootedUdid; it still lists for a reused sim with nobootedUdid, and for abootedUdidthat names another sim.ensureOwnedDevicereports the boot it performed on the created path and on the reuse-after-shutdown path, reports nothing on the already-booted path, and the persisted registry record is unchanged ({ deviceUdid, owned, deviceName }).ios-command.test.ts: an end-to-end run wired to the realensureBootedwith a fake clock that charges 8 s persimctl list devices-- the phase line readsbooted (0ms)on the fresh-boot path andbooted (8s)on the path that has to list. Ablation: dropping the new early return inensureIosBootedfails both this test and the engine one.pnpm run format:check,lint,build,typecheck,pnpm test(83 files, 3336 tests),pnpm run knipall pass on this branch.Fixes #268