using Akka.Actor; using Akka.Cluster; using ZB.MOM.WW.ScadaBridge.Commons.Messages.Health; using ZB.MOM.WW.ScadaBridge.HealthMonitoring; using ZB.MOM.WW.ScadaBridge.Host.Actors; namespace ZB.MOM.WW.ScadaBridge.Host.Health; /// /// Provides cluster node statuses from Akka.NET cluster membership for health reporting. /// public class AkkaClusterNodeProvider : IClusterNodeProvider { private readonly AkkaHostedService _akkaService; private readonly string _siteRole; /// /// Initializes a new . /// /// The Akka hosted service providing access to the actor system. /// The Akka cluster role used to filter relevant member nodes. public AkkaClusterNodeProvider(AkkaHostedService akkaService, string siteRole) { _akkaService = akkaService; _siteRole = siteRole; } /// public bool SelfIsPrimary { get { var system = _akkaService.ActorSystem; if (system == null) return false; var cluster = Cluster.Get(system); return ClusterActivityEvaluator.SelfIsOldest(cluster, _siteRole); } } /// public IReadOnlyList GetClusterNodes() { var system = _akkaService.ActorSystem; if (system == null) return []; var cluster = Cluster.Get(system); var oldest = ClusterActivityEvaluator.OldestUpMember(cluster, _siteRole); var nodes = new List(); foreach (var member in cluster.State.Members) { if (!member.HasRole(_siteRole)) continue; var hostname = member.Address.Host ?? member.Address.ToString(); var isOnline = member.Status == MemberStatus.Up; var isPrimary = oldest != null && member.UniqueAddress.Equals(oldest.UniqueAddress); var role = isPrimary ? "Primary" : "Standby"; nodes.Add(new NodeStatus(hostname, isOnline, role)); } // If we have unreachable members, add them as offline foreach (var unreachable in cluster.State.Unreachable) { if (!unreachable.HasRole(_siteRole)) continue; // Don't duplicate if already in members list if (nodes.Any(n => n.Hostname == (unreachable.Address.Host ?? unreachable.Address.ToString()))) continue; var hostname = unreachable.Address.Host ?? unreachable.Address.ToString(); nodes.Add(new NodeStatus(hostname, false, "Standby")); } return nodes; } }