Skip to content

fix(chromium): let attached pages install service workers - #293

Merged
shinkuan merged 1 commit into
v3from
fix/chromium-sw-register-hang
Oct 21, 2026
Merged

shinkuan merged 1 commit into
v3from
fix/chromium-sw-register-hang

Conversation

@shinkuan

Copy link
Copy Markdown
Owner

Fixes #292.

Problem

With [capture] mode = "chromium", Majsoul stays on a black screen or the logo whenever a new sw.js version has to install (game update, cleared site data, fresh profile). The page's navigator.serviceWorker.register() never settles, and the WebGL boot awaits it, so the Unity build is never requested.

Cause

chromiumoxide 0.9.1 auto-attaches to every page with Target.setAutoAttach { waitForDebuggerOnStart: true }. A new service worker therefore starts paused. When chromiumoxide sees it attach, it sends Runtime.runIfWaitingForDebugger and Target.detachFromTarget back to back, without waiting for the resume to land. If the worker's main script is still loading at that point, the resume is lost with the session. The worker stays in the paused-on-start state (status: new, runningStatus: starting), and every later registration job for that scope queues behind it. That is why a registration of a 404 script hangs too, instead of rejecting.

A fast script response hides the race. In local tests it shows up once sw.js takes about 300 ms, which a CDN response easily does. Re-arming auto-attach without the pause from Akagi after attaching does not help: the game registers its worker while chromiumoxide is still initializing the page, before Akagi gets the Page.

Fix

Patch chromiumoxide ([patch.crates-io]) to shinkuan/chromiumoxide@17c2e5a. That is the v0.9.1 tag plus one commit that auto-attaches with waitForDebuggerOnStart: false. chromiumoxide does nothing while a target is paused and resumes each one right away, so the pause has no use. The patch can be dropped once a chromiumoxide release carries the fix.

Cargo.lock changes only the source of the four chromiumoxide crates.

Tests

  • New tests/chromium_service_worker.rs (ignored by default, needs a Chromium browser). It runs the real cdp::run loop against headless Chrome and opens a page that registers a service worker whose script is served 1.5 s late.

    • Without the patch it fails with register=timeout&ready=timeout.
    • With the patch it passes.
  • tests/chromium_telemetry_block.rs (ignored) still passes, including the dedicated-worker beacon.

  • Real game.maj-soul.com in headless Chrome 155, with a harness that uses chromiumoxide the same way:

    build result
    unpatched worker never activates, 11 resources, no framework.js
    patched worker activated, 207 resources, framework.js loaded
    unpatched, CDP connected 20 s late (control) same as patched
  • cargo fmt --check, cargo clippy --all-targets -D warnings and cargo test pass.

chromiumoxide 0.9.1 auto-attaches to every page with
waitForDebuggerOnStart: true. A service worker registered under it starts
paused, and chromiumoxide resumes and detaches it in the same breath. When
the worker's main script is still loading at that moment, the resume is
lost with the session: the worker stays paused-on-start, and the page's
navigator.serviceWorker.register() never settles. Majsoul's WebGL boot
awaits that registration, so the game stays on a black screen or the logo
whenever a new sw.js version has to install.

Patch chromiumoxide to a fork that is 0.9.1 plus one commit that
auto-attaches without pausing. Nothing is done while an auto-attached target
is paused, so the pause has no use.

The new browser test registers a worker whose script is served late, with
the real CDP loop attached. It times out without the patch and passes with
it.
@shinkuan

Copy link
Copy Markdown
Owner Author

/build-artifacts

@github-actions

Copy link
Copy Markdown

✅ PR build completed

Commit: 9b80dd6ec366

Artifacts expire after 14 days.
View workflow run

@shinkuan
shinkuan merged commit f1535df into v3 Oct 21, 2026
4 checks passed
@shinkuan
shinkuan deleted the fix/chromium-sw-register-hang branch October 21, 2026 15:48
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.

chromium capture: chromiumoxide auto-attach leaves new service workers paused → serviceWorker.register() stalls 5 min, Unity doesn't boot

1 participant