Phase 3 PR 34 — Host-status publisher (Server) + /hosts drill-down page (Admin) #33
Reference in New Issue
Block a user
Delete Branch "phase-3-pr34-host-status-publisher-page"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes LMX follow-up #7 by wiring together the data layer from PR 33. Two halves: a Server-side publisher that writes per-host status rows, and an Admin-side page that renders them with per-cluster grouping and stale-row flagging.
Server half —
HostStatusPublisherBackgroundServicethat every 10 seconds walks every registered driver, skips drivers withoutIHostConnectivityProbe, callsGetHostStatuses(), and upserts oneDriverHostStatusrow per(NodeId, DriverInstanceId, HostName).LastSeenUtcadvances unconditionally every tick (heartbeat);State+StateChangedUtconly change on an actual transition. That lets the Admin distinguish "still Running" from "freshly transitioned to Running".GetHostStatusesthrowing logs + skips that driver this tick. DB unreachable logs + retries next heartbeat (no buffering — the next snapshot is more useful than replaying stale transitions).NodeBootstrap.RegisterAsynccalls land first, then immediate tick so a fresh Server surfaces its topology without waiting a full interval.OnHostStatusChangedsubscription is an optional follow-up (DriverHostdoesn't expose registration lifecycle events today).Requires
Microsoft.EntityFrameworkCore.SqlServeron the Server project +AddDbContext<OtOpcUaConfigDbContext>inProgram.cs(first direct SQL access from the Server — LocalCache is LiteDB-only).Admin half —
/hostspageHostStatusServiceleft-joinsDriverHostStatusagainstClusterNodeonNodeIdso rows persist even when the node row doesn't exist yet (first-boot bootstrap case — rendered under(unassigned)).StaleThreshold = 30scovers one missed heartbeat plus clock skew + GC pauses.IServiceScopeFactorytimer pattern matchingFleetStatusPoller+ the Fleet dashboard.Fleet statusandClusters.Tests
HostStatusPublisherTests(4 new Integration cases, throwaway DB per run):LastSeenUtcwithout creating duplicate rows (upsert end-to-end).StateANDStateChangedUtc(1ms tolerance fordatetime2(3)rounding — documented inline).MapStatetranslates everyHostStateenum member.Test posture
Deferred (explicit in
lmx-followups.md)