using Akka.Cluster; using ZB.MOM.WW.ScadaBridge.Host.Actors; using ZB.MOM.WW.ScadaBridge.InboundAPI; namespace ZB.MOM.WW.ScadaBridge.Host.Health; /// /// Production implementation of /// backed by the running Akka.NET cluster. /// /// The inbound API is "Central cluster only (active node)" — a standby central /// node must not execute method scripts or Route.To() calls. Active = /// the oldest Up member (the singleton host), evaluated by /// — NOT /// the cluster leader, whose address-ordered definition diverges from singleton /// placement after a restart (review 01 [High]). This is the same evaluator /// backing the shared ActiveNodeHealthCheck registered on the active tier /// — both route to ClusterActiveNode — so /// can return HTTP 503 on a standby. /// /// Registered only in the Central-role branch of Program.cs. The gate /// is resolved per request from HttpContext.RequestServices; while the /// AkkaHostedService is still warming up (ActorSystem == null) /// or the node has not yet reached , this /// implementation reports IsActiveNode == false — the safe-by-default /// answer matching the standby case. /// public sealed class ActiveNodeGate : IActiveNodeGate { private readonly AkkaHostedService _akkaService; /// Initializes a new bound to the given Akka hosted service. /// The Akka hosted service exposing the cluster's . public ActiveNodeGate(AkkaHostedService akkaService) { _akkaService = akkaService; } /// public bool IsActiveNode { get { var system = _akkaService.ActorSystem; if (system == null) return false; var cluster = Cluster.Get(system); return ClusterActivityEvaluator.SelfIsOldest(cluster); } } }