feat(adminui): ScriptLog live-pill bound to broadcaster health

Subscribe ConnectionStateChanged before reading IsConnected (subscribe-then-read
idiom, matches DriverStatusPanel) so no transition is missed. Add
OnConnectionStateChanged handler that marshals to the circuit sync context via
InvokeAsync. Dispose unsubscribes both events.

Reconnect-overlay: App.razor loads _framework/blazor.web.js and contains no
custom #components-reconnect-modal element; .NET 10 Blazor's default reconnect
overlay is active automatically — no custom markup needed.

No unit tests; live-verify follows.
This commit is contained in:
Joseph Doherty
2026-06-11 09:37:19 -04:00
parent d29c933499
commit 19ec656cdc
@@ -118,10 +118,15 @@ else
// Live tail straight from the in-process broadcaster (fed by ScriptLogSignalRBridge off the
// 'script-logs' DPS topic). Blazor Server can't self-connect a SignalR HubConnection behind
// a reverse proxy — see IInProcessBroadcaster — so we subscribe in-process instead.
// Subscribe the state-change event BEFORE reading IsConnected so no transition is missed.
ScriptLogs.ConnectionStateChanged += OnConnectionStateChanged;
ScriptLogs.Received += OnEntry;
_connected = true;
_connected = ScriptLogs.IsConnected;
}
private void OnConnectionStateChanged(bool connected) =>
InvokeAsync(() => { _connected = connected; StateHasChanged(); });
private void OnEntry(ScriptLogEntry entry) =>
// Marshal both the mutation and the re-render onto the circuit sync context so this can't
// race ClearAsync (which runs there) over the shared _rows list.
@@ -146,5 +151,9 @@ else
_ => "chip-idle",
};
public void Dispose() => ScriptLogs.Received -= OnEntry;
public void Dispose()
{
ScriptLogs.ConnectionStateChanged -= OnConnectionStateChanged;
ScriptLogs.Received -= OnEntry;
}
}