Skip to content

Start native worker only after CSS cache configuration #111

Description

@wieslawsoltes

Problem

Enabling the compiled CSS cache in the Code OSS host exposes a startup-order race in webscene_engine. The constructor starts worker_ in its member initializer list, then configures the process CSS compilation-cache directory in the constructor body. The worker can begin loading and parsing the document before constructor setup is complete.

On the macOS 12 deployment-target build used by AppScene, the packaged VS Code OSS workbench remains in continuous visible rendering after startup:

  • visible idle presentations: 119.010/sec
  • visible idle CPU: 1.089%
  • scene generation and publication continue at display refresh rate

The prior runtime and a build where the worker starts after cache setup both settle:

  • visible idle presentations: 0/sec
  • hidden idle presentations: 0/sec
  • visible idle CPU: 0.042%

A macOS 26-target rebuild happened to mask the race, so deployment target and compiler timing affect reproduction.

Root cause

worker_ begins during member initialization. Process-wide CSS cache setup happens later in the constructor body, despite the class invariant that the worker should only observe fully configured state. Bypassing CSS event-cache replay still reproduces 119.048 presentations/sec, ruling out replay semantics.

Proposed fix

Default-construct the final std::jthread member. In the constructor body:

  1. Configure the CSS compilation-cache directory.
  2. Mark constructor setup complete.
  3. Assign/start worker_.

Add a worker-entry invariant guard so future ordering regressions fail closed.

Regression coverage

  • Repeatedly construct configured engines with a nonempty cache directory and execute a worker task.
  • Assert the worker never observes partially configured engine state.
  • Keep the packaged performance gates:
    • idle.visiblePresentationsPerSecond <= 5
    • idle.hiddenPresentationsPerSecond <= 2
  • Validate with CMAKE_OSX_DEPLOYMENT_TARGET=12.0, where the race reproduces reliably.

Acceptance

  • Native lifecycle regression passes.
  • Existing native runtime, CSS parser/cache, WPT, and package gates pass.
  • Code OSS reaches 0 idle visible/hidden presentations per second after warmup.
  • No change to CSS cache contents or public ABI.

Activity

  1. wieslawsoltes commented on Sep 16, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Follow-up qualification corrected the causal attribution. The constructor-order defect and its fail-closed lifecycle regression remain valid, but the earlier two-second 0-present sample was too short and ended before the delayed VS Code status animation path. A full 15-second warm-up plus five-second sample against the packaged 7015c27f runtime still reproduced 608 visible presents in 5.064 seconds (120.063/s).

    Bounded frame-demand tracing identified a visible finite span.codicon.codicon-bracket.wiggle rotation animation. VS Code expects its animationend listener to remove that class; WebScene does not yet dispatch CSS animation events. That separate correctness/performance blocker is tracked in #113. Issue #111 should therefore be reviewed as startup/lifecycle hardening and must not claim closure of the packaged idle-redraw regression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions