Skip to content

Report swap growth and wallpaper refreshes in lane health, and find SpringBoard - #196

Merged
arun279 merged 1 commit into
feat/expo-nativefrom
fix/lane-health-poster-refresh
Oct 22, 2026
Merged

arun279 merged 1 commit into
feat/expo-nativefrom
fix/lane-health-poster-refresh

Conversation

@arun279

@arun279 arun279 commented Oct 22, 2026

Copy link
Copy Markdown
Owner

The failure

#195's run 39862150429 failed native-e2e-ios-light (discovery) (job 120115822649) before any tap. Maestro's deviceInfo raised SocketTimeoutException: Connect timed out, followed by Device became unreachable. The artifacts show:

  • The runner and the tap proxy started and answered. maestro-runner.log has deviceInfo: 200 and then deviceInfo through the tap proxy: 200 at 22:11:30. Maestro's status check, deviceInfo, setPermissions and terminateApp all reached the runner through the proxy between 22:11:56 and 22:11:57. So it is neither a start-up race nor the driver dying at start-up. maestro-runner.mjs reports ready only after both answer.

  • After 22:12:02 no request reached the runner, but nothing had died. Maestro started assertVisible at 22:12:04.9, and its first deviceInfo gave up at 22:12:49.9 after 45 s of connect timeouts. The runner's log has no connection after 22:12:02. The process list taken after the flow still shows the proxy's node (7593), its xcodebuild (7802), the runner (8433) and Cue (10576). The proxy logged no unreachable-runner error, so the requests never reached it either.

  • The host started swapping hard at that moment.

    Swap used Swapouts
    Before the flow 0 0
    After the flow 536 MB 35,828

    Lane health logged 1,239 MB paged in during the flow. The proxy's node process sat at 14 MB resident, mostly paged out.

  • PosterBoard ran a wallpaper gallery refresh just before. At 22:12:01 it started pushUpdatedPosterDescriptors ("Push To Proactive"), and about ten wallpaper extensions came up: Gradient, Mercury, Kaleidoscope, Aegir, Unity, Rhizome, Weather, Pride, Extragalactic. Lane health's process census shows PosterBoard at 193 MB, MercuryPosterExtension at 161 MB, and so on. The wallpaper processes wrote 29,305 of the run's 57,910 simulator log lines. The discovery lanes in Deduplicate CI setup and drop stale configuration #193's run 39855874496 and Prune tautological, outmoded and duplicated tests #192's run 39850551247 logged no gallery refresh, and 24 and 284 wallpaper lines.

I could not prove from the artifacts how the swap turned into connect timeouts, as opposed to slow replies. The timing and the 29,305 against 24 or 284 wallpaper lines point at the gallery refresh, which is simulator behaviour rather than ours.

Change

So the next lane that stalls this way says so in its health report:

  • Lane health reports how far swap grew during the flow (sysctl vm.swapusage before and after) and how many wallpaper gallery refreshes PosterBoard ran, recording the first five refresh lines.
  • A real bug in lane health itself: its SpringBoard spindump never ran on this runtime. The run's health log says "could not find SpringBoard to sample", because the lookup assumed the process path has no space, and the iOS 26.4 runtime's path contains iOS 26.4.simruntime. The lookup now matches the whole path.

A possible mitigation for later is turning off PosterBoard's gallery refresh the way ios-disabled-daemons.tsv turns off other daemons. I didn't do it here: SpringBoard depends on PosterBoard for the home and lock screen, and this one failure isn't evidence enough to justify the risk.

Tests

  • New unit tests using lines from this run:
    • swap in use parsed from sysctl;
    • one refresh counted per gallery refresh, ignoring that refresh's other lines;
    • SpringBoard found under the real iOS 26.4.simruntime path.
  • The end-to-end lane-health test expects the two new lines.

Mutation check, each applied alone:

Break Caught by
The old SpringBoard pattern the SpringBoard test
Counting every refresh line the refresh test
Reading total swap instead of used the swap test and the end-to-end test
Dropping the refresh line the end-to-end test

Footprint

No product code changes. CI and tooling: scripts/lane-health.mjs gains about 20 lines. Configuration: one cspell word. Tests: about 30 lines.

pnpm check passes on Node 22.23.4.

…pringBoard

Run 39862150429's iOS discovery lane lost its runner a minute into the
flow: Maestro's connections timed out while the runner, the tap proxy and
xcodebuild were all still running. In that minute PosterBoard ran a
wallpaper gallery refresh, which started about ten wallpaper extensions
of 100 to 200 MB each, and the host went from no swap to 536 MB. Passing
discovery lanes in #193's and #192's runs logged no refresh.

Lane health now reports how far swap grew during the flow and how many
wallpaper gallery refreshes PosterBoard ran, with the first five refresh
lines, so the next lane that stalls this way says so.

Its SpringBoard spindump never ran on this runtime: the lookup expected
no space in the process path, and the iOS 26.4 runtime lives under
"iOS 26.4.simruntime". It matches the whole path now.
@github-actions

Copy link
Copy Markdown

Pull request footprint

measurement base to head
Product code lines in core/src, native/src, native/app, and native/modules +0
Test lines in test, packages/*/{test,__tests__,e2e}, and .maestro +29
CI and tooling lines in .github and scripts +22
Product comment lines identified by a comment prefix +0

User-delivered artifact sizes

measurement base head delta
Expo iOS JavaScript bundle, raw file 5.45 MB 5.45 MB 0 B
Expo Android JavaScript bundle, raw file 5.48 MB 5.48 MB 0 B
Firebase tester APK, arm64-v8a and all densities 41.16 MB 41.16 MB 0 B
Play download estimate, XXXHDPI arm64-v8a English Android 15 19.83 MB 19.83 MB 0 B

Most complex product function

measurement base head
Cyclomatic complexity, oxlint complexity 10 10
Cognitive complexity, Biome noExcessiveCognitiveComplexity 15 15

@arun279
arun279 merged commit 8bfc597 into feat/expo-native Oct 22, 2026
24 checks passed
@arun279
arun279 deleted the fix/lane-health-poster-refresh branch October 22, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant