fix(dashboard): alarms feed doc row + monitor-contract comment + mid-truncation attach test

The In-process page feeds table still described the alarms page's subscription as
provider status only, contradicting the three passages updated in 7b6dfba.

The loop's catch-all comment (and the cadence bullet that repeated it) claimed the
monitor completes a subscriber's stream on restart. It does not: ClearCache pushes
snapshot_status(false) through the still-open channel, and a subscriber is only
completed-with-error on a failed TryWrite, or removed by its own disposal.

The SnapshotStatus arm's priming claim had no test behind it — every push test
attached to an untruncated feed and pushed the edge itself. ScriptedAlarmFeed now
replays an optional open sequence, and a new test attaches to a feed already
primed provider_status then snapshot_status(truncated) and asserts the banner
comes up with no edge pushed after render.
This commit is contained in:
Joseph Doherty
2026-08-18 06:49:20 -04:00
parent d3ac52758c
commit f57a6ae5ff
3 changed files with 63 additions and 8 deletions
+4 -4
View File
@@ -186,7 +186,7 @@ hubs stay for the audience that genuinely needs a wire.
|---|---|---|
| every page deriving from `DashboardPageBase` | `IDashboardSnapshotFeed.WatchAsync` | `DashboardSnapshotFeed` (singleton) multicasting one `IDashboardSnapshotService.WatchSnapshotsAsync` enumeration |
| `SessionDetailsPage` | `IDashboardSessionEventSubscriber.Subscribe(sessionId)` | `DashboardEventBroadcaster` — the same singleton the session mirror publishes to, registered behind both interfaces |
| `AlarmsPage` | `IGatewayAlarmService.StreamAsync` | the central alarm monitor, **provider status only**; the alarm rows still come from the 3 s `QueryAlarmsAsync` poll |
| `AlarmsPage` | `IGatewayAlarmService.StreamAsync` | the central alarm monitor, **gateway-status frames only**`provider_status` for the badge and `snapshot_status` for the truncated-snapshot banner; the alarm rows still come from the 3 s `QueryAlarmsAsync` poll |
The snapshot feed multicasts rather than handing each page its own enumeration:
`WatchSnapshotsAsync` is not multicast on its own — each enumeration owns a timer
@@ -288,9 +288,9 @@ Both seams consume the same producing services, so they share these cadences:
to its internal dashboard-mirror subscriber (independent of any gRPC `StreamEvents`);
- the alarms page's status feed resubscribes one second after its
`IGatewayAlarmService.StreamAsync` enumeration ends — the monitor completes a
subscriber's stream when it falls behind and again when it restarts, both
recoverable by resubscribing — and the badge and banner hold their last values in
between. That feed carries both gateway-status frames: `provider_status` drives the
subscriber's stream only when that subscriber has fallen behind, which resubscribing
recovers (a monitor restart keeps the channel and pushes cleared status frames through
it) — and the badge and banner hold their last values in between. That feed carries both gateway-status frames: `provider_status` drives the
badge, and `snapshot_status` drives the truncated-snapshot banner, so the caveat
appears on the monitor's verdict change rather than up to three seconds later. Every
subscriber is primed with a `snapshot_status` frame at open, so a page attaching