refactor(health): move ICentralHealthAggregator and SiteHealthState to Commons (ScadaBridge#71)

Interface goes to Commons.Interfaces.Services and the state record to
Commons.Messages.Health, so CentralCommunicationActor no longer needs the
HealthMonitoring namespace. Implementation stays in HealthMonitoring.

Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
Joseph Doherty
2026-11-09 12:37:04 -05:00
parent 4918210b78
commit 3ae3f1bcef
28 changed files with 33 additions and 10 deletions
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
@@ -1,5 +1,7 @@
@page "/monitoring/health"
@attribute [Authorize]
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Messages.Health
@using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Health
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Types
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using Microsoft.AspNetCore.Components.Authorization;
using ZB.MOM.WW.ScadaBridge.CentralUI.Auth;
using ZB.MOM.WW.ScadaBridge.Security;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.HealthMonitoring;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Types;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Services;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
@@ -1,6 +1,6 @@
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Health;
namespace ZB.MOM.WW.ScadaBridge.HealthMonitoring;
namespace ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
/// <summary>
/// Interface for central-side health aggregation.
@@ -21,7 +21,7 @@ public interface ICentralHealthAggregator
/// cadence is owned by the Cluster Infrastructure / <c>SiteCommunicationActor</c>
/// (the application-level heartbeat to central, sent every
/// <c>CommunicationOptions.TransportHeartbeatInterval</c> — 5s by default);
/// the 60s <see cref="HealthMonitoringOptions.OfflineTimeout"/> therefore
/// the 60s <c>HealthMonitoringOptions.OfflineTimeout</c> therefore
/// tolerates several missed heartbeats. A heartbeat for a site with no
/// aggregator state yet (e.g. just after a central restart/failover)
/// registers that site as online with no
@@ -1,6 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Health;
namespace ZB.MOM.WW.ScadaBridge.HealthMonitoring;
namespace ZB.MOM.WW.ScadaBridge.Commons.Messages.Health;
/// <summary>
/// In-memory state for a single site's health, stored by the central aggregator.
@@ -59,7 +57,7 @@ public sealed record SiteHealthState
/// <summary>
/// Gets a value indicating whether the site is online (heartbeats still
/// arriving) but has sent no full <see cref="SiteHealthReport"/> within
/// <see cref="HealthMonitoringOptions.MetricsStaleTimeout"/>. This is a signal
/// <c>HealthMonitoringOptions.MetricsStaleTimeout</c>. This is a signal
/// <em>distinct</em> from liveness: a site whose HealthReportSender died keeps
/// heartbeating and would otherwise show "online with frozen metrics forever".
/// Cleared whenever a fresh report is processed. Heartbeats never set or clear
@@ -69,12 +67,12 @@ public sealed record SiteHealthState
/// <summary>
/// Gets the instant this site's LocalDb replication oplog backlog first rose above
/// <see cref="HealthMonitoringOptions.LocalDbBacklogThreshold"/> and stayed there, or
/// <c>HealthMonitoringOptions.LocalDbBacklogThreshold</c> and stayed there, or
/// <c>null</c> if the backlog is not currently above it (register row 33).
/// </summary>
/// <remarks>
/// The anchor for the *sustained* backlog badge: the badge shows only once
/// <see cref="HealthMonitoringOptions.LocalDbBacklogSustainedFor"/> has elapsed since this
/// <c>HealthMonitoringOptions.LocalDbBacklogSustainedFor</c> has elapsed since this
/// instant. Holding a start time rather than a boolean is what makes the signal survive the
/// expected daily purge burst — that spike raises the backlog for a drain's worth of
/// reports and then clears this back to null, never reaching the dwell.
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using Akka.Actor;
using Akka.Cluster.Tools.PublishSubscribe;
using Akka.Event;
@@ -10,7 +11,6 @@ using ZB.MOM.WW.ScadaBridge.Commons.Messages.Communication;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Deployment;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Health;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Notification;
using ZB.MOM.WW.ScadaBridge.HealthMonitoring;
namespace ZB.MOM.WW.ScadaBridge.Communication.Actors;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using Akka.Actor;
using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using System.Collections.Concurrent;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Kpi;
namespace ZB.MOM.WW.ScadaBridge.HealthMonitoring.Kpi;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Kpi;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Kpi;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
@@ -1,3 +1,4 @@
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;