Skip to content

refactor: Split server activity state from stale-project tracking#1474

Open
RandomByte wants to merge 5 commits into
mainfrom
refactor/server-stale-state
Open

refactor: Split server activity state from stale-project tracking#1474
RandomByte wants to merge 5 commits into
mainfrom
refactor/server-stale-state

Conversation

@RandomByte

Copy link
Copy Markdown
Member

Problem

The server banner mixed two separate things into one #serverState value: what the server is doing (activity) and which projects are up-to-date (staleness). Any non-fresh project forced the whole server to stale, including a dependency that is merely INITIAL, never requested, with a stale cache. Under lazy building nobody rebuilds an unrequested project, so the server got stuck on stale and never returned to ready, even though every resource was still servable on request.

Change

  • Activity (BuildServer's #serverState) drops STALE. The resting state is IDLE, rendered as ready. #reconcileServerState settles on IDLE whether projects are fully fresh or stale-remaining; background validation still runs first when INITIAL projects may be cache-clean.
  • Stale set is reported independently via a new #emitStale(), de-duplicated against the last set so the several emission sites (reconcile, eager source-change, watcher recovery, startup) don't re-emit an unchanged signal.
  • Logger side: Serve#stale(staleProjects) replaces stale(changedProjects). InteractiveConsole records the set on serve-stale and re-renders without an activity transition; the ready line appends a dimmed · N projects stale count. The standalone stale render state is removed.

The server banner collapsed the dev server's lifecycle into one Status line
whose `stale` value conflated two orthogonal things: what the server is doing
(activity) and which projects are up-to-date. This meant a project that went
stale but was never requested held the banner on `stale` forever.

Split the two dimensions on the logger side:

- Serve logger: replace `stale(changedProjects)` with `stale(staleProjects)`,
  emitting `serve-stale`. The stale set is reported independently of the activity
  state, so it can update while the server stays `ready`.
- InteractiveConsole: `serve-stale` records the stale set without an activity
  transition; drop the STALE activity handling.
- Build state + render: remove the STALE activity state; the READY line appends a
  `· N projects stale` count when any project is stale.
…cking

BuildServer exposed a single `#serverState` scalar and derived it partly by
aggregating per-project build status via `#getStaleProjectNames()`: any non-fresh
project (including a dependency that is merely INITIAL, never requested, with a
stale cache) forced the state to STALE. Under lazy building nobody rebuilds an
unrequested project, so the server wedged on `stale` and never returned to
`ready`, even though every resource was still servable on request.

Separate the two dimensions:

- Activity (`#serverState`): remove STALE. The resting state is IDLE ("ready");
  SETTLING stays (it is tied to the file-watcher settle windows).
- Stale set: `#emitStale()` reports the stale-project set to the ServeLogger,
  de-duplicated against the last set. Called from the reconcile close, the eager
  source-change path, watcher recovery, and the no-initial-build startup.

`#reconcileServerState` no longer falls back to STALE: fully-fresh and
stale-remaining both resolve to IDLE plus a stale-set report; background
validation still runs first when INITIAL projects may be cache-clean. Build
triggering is unchanged; only how state is presented.
The reconciler already computes the stale set; #emitStale swept
#projectBuildStatus again for the same result. Let it accept a
pre-computed set and pass the reconciler's, halving the scans on that
path. Other call sites still recompute.
@RandomByte
RandomByte force-pushed the refactor/server-stale-state branch from 018b57b to 21b5e85 Compare July 23, 2026 15:59
The Serve#stale() parameter was named changedProjects, framing the input as
a diff of what changed. The method reports the full current stale set, so
staleProjects names it for what it is. The serve-stale event payload key and
the InteractiveConsole writer state (setStale, render, the build-state field)
follow suit, matching the sibling event keys pendingProjects and
validatingProjects.
@RandomByte
RandomByte marked this pull request as ready for review July 24, 2026 08:21
@RandomByte
RandomByte requested a review from a team July 24, 2026 08:21
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