fix(web): a delivered on-demand start reads as starting until the display acts on it

On ledpi (three cold starts) the display acknowledged the start as its
socket opened, then took ~5 s to act on it while Vegas built its first
strip; the status routes meanwhile showed the display's own idle state, so
a UI polling every 700 ms flashed idle.

The display's on-demand state now names the request it answers
(request_id). A delivered start keeps reading as status "starting" with
delivered: true, in /display/on-demand/status and as on_demand_pending in
/display/current-status, until the display publishes state for that
request id (a display without the field: any state newer than the
delivery), for at most DELIVERED_SHOWN_SECONDS (30 s). The display's
startup state, which can be published after the acknowledgement, names no
request and does not end it.

Tests: stays starting against the startup idle state (no id, an older id);
the matching active state and the matching error take over; an older
display's newer state takes over; the 30 s cap; the display's state names
its request. Mutation check: 11 mutants, 11 killed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-10-05 13:25:12 -04:00
co-authored by Claude Opus 5.5
parent 09a846a717
commit f5e7f2fc6d
8 changed files with 177 additions and 29 deletions
+3 -1
View File
@@ -510,7 +510,9 @@ with HTTP `202`. The web process sends the request until the display takes
it, for up to `wait_seconds` (45 after a cold start, 10 when the service was
already running). Follow it with `GET /api/v3/display/on-demand/status`:
its `state` is `{status: "starting", source: "web", request_id, ...}` while
it waits, the display's own state once delivered, or `{status: "error",
it waits, and still `starting` with `delivered: true` once the display has
acknowledged it but not yet published the state for that `request_id` (at
most 30 s), then the display's own state, or `{status: "error",
error: "start-timeout"}` (or the socket's reason) if it never was;
`GET /api/v3/display/current-status` carries the same as
`on_demand_pending`. A newer start replaces a pending one; a stop cancels it.