Repository navigation
fix(wasm-sw): boot shell waits for the worker's claim before loading the app - #463
Merged
Merged
Conversation
…the app The boot shell reloaded as soon as register() resolved without a controller, before the worker had installed. When the worker's clients.claim() then landed while a later shell was still awaiting register() (which waits on the /sw.js update check), that shell saw a controller, printed "Service worker active." and stopped: the page stayed the static shell and the CWIST app never loaded. This is the intermittent `wasm-sw-browser-test` timeout on "Session visits" (6 CI failures on 10-27/10-29, all at that step). The shell is only ever what the network serves (a controlled "/" is answered by CWIST, and the cache serves it only as /index.html), so: with a controller, load "/" right away; without one, wait for controllerchange and then load it. The test now reports where it stopped (URL, controlled, shell status, worker errors) instead of a bare selector timeout. Reproduced locally by delaying the /sw.js update check and the core .wasm fetches by 3 s: 2 of 3 runs stuck before the fix, 6 of 6 pass after.
gg582
added a commit
that referenced
this pull request
Oct 29, 2026
cherry-pick: wasm-sw boot shell waits for the worker's claim (#463) to main
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
Fixes the intermittent
wasm-sw-browser-testfailure,page.waitForSelector: Timeout 30000ms exceeded … 'text=Session visits'. It failed 6 times on 10-27/10-29, on dev pushes and PRs alike (e.g. #461, #462), always at the same step. It is not a test flake: a race in the example's boot shell (example/wasm-service-worker/index.html) can leave a real user on the static shell too.Cause
The shell called
register('/sw.js'), and if no worker controlled the page yet it reloaded immediately, before the worker had installed. The reload loops until the worker is active. The worker'sactivatehandler then runsclients.claim().The problem is when that claim lands while a later shell is still awaiting
register(). For an existing registration,register()waits on the/sw.jsupdate check. That shell then sees a controller, prints "Service worker active." and returns. Nothing reloads it, so the static shell stays up and the CWIST page ("Session visits") never appears. The test'scontroller !== nullwait passes and the selector wait times out, which matches the CI log.Fix
The shell is only ever what the network serves. A controlled
/is answered by CWIST through the worker, and the worker's cache serves the file only as/index.html. Whenever the shell's script runs, the app has therefore not been loaded:register(), or opened as/index.html):location.replace('/').controllerchange(the claim), thenlocation.replace('/').The test now reports where it stopped instead of a bare selector timeout: URL, whether the page is controlled, the shell's status text, and worker errors.
Verification (local, Chromium via Playwright 1.63, the CI pin)
/sw.jsupdate check and the core.wasmfetches by 3 s, as on a busy runner. 2 of 3 runs got stuck with exactly the CI state: shell status "Service worker active.",controlled=true, no CWIST page./index.htmlonce the worker is installed lands on the CWIST page at/after 2 navigations.