Closes the HostedService half of Phase 6.1 Stream E.2 flagged as a follow-up when the DriverResilienceStatusTracker shipped in PR #82. The Admin /hosts column refresh + SignalR push + red-badge visual (Stream E.3) remain deferred to the visual-compliance pass — this PR owns the persistence story alone. Server.Hosting: - ResilienceStatusPublisherHostedService : BackgroundService. Samples the DriverResilienceStatusTracker every TickInterval (default 5 s) and upserts each (DriverInstanceId, HostName) counter pair into DriverInstanceResilienceStatus via EF. New rows on first sight; in-place updates on subsequent ticks. - PersistOnceAsync extracted public so tests drive one tick directly — matches the ScheduledRecycleHostedService pattern for deterministic timing. - Best-effort persistence: a DB outage logs a warning + continues; the next tick retries. Never crashes the app on sample failure. Cancellation propagates through cleanly. - Tracks the bulkhead depth / recycle / footprint columns the entity was designed for. CurrentBulkheadDepth currently persisted as 0 — the tracker doesn't yet expose live bulkhead depth; a narrower follow-up wires the Polly bulkhead-depth observer into the tracker. Tests (6 new in ResilienceStatusPublisherHostedServiceTests): - Empty tracker → tick is a no-op, zero rows written. - Single-host counters → upsert a new row with ConsecutiveFailures + breaker timestamp + sampled timestamp. - Second tick updates the existing row in place (not a second insert). - Multi-host pairs persist independently. - Footprint counters (Baseline + Current) round-trip. - TickCount advances on every PersistOnceAsync call. Full solution dotnet test: 1225 passing (was 1219, +6). Pre-existing Client.CLI Subscribe flake unchanged. Production wiring (Program.cs) example: builder.Services.AddSingleton<DriverResilienceStatusTracker>(); builder.Services.AddHostedService<ResilienceStatusPublisherHostedService>(); // Tracker gets wired into CapabilityInvoker via OtOpcUaServer resolution // + the existing Phase 6.1 layer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.0 KiB
6.0 KiB