using Akka.Cluster; using Microsoft.Extensions.Diagnostics.HealthChecks; using ZB.MOM.WW.ScadaBridge.Host.Actors; namespace ZB.MOM.WW.ScadaBridge.Host.Health; /// /// Health check that returns healthy only if this node is the active (leader) node /// in the Akka.NET cluster. Used by Traefik to route traffic to the active node. /// public class ActiveNodeHealthCheck : IHealthCheck { private readonly AkkaHostedService _akkaService; /// Initializes a new with the given Akka hosted service. /// The Akka hosted service providing access to the actor system and cluster state. public ActiveNodeHealthCheck(AkkaHostedService akkaService) { _akkaService = akkaService; } /// Returns healthy if this node is the cluster leader (active node); otherwise returns unhealthy. /// Health check context providing registration details. /// Cancellation token. public Task CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { var system = _akkaService.ActorSystem; if (system == null) return Task.FromResult(HealthCheckResult.Unhealthy("ActorSystem not yet available.")); var cluster = Cluster.Get(system); var self = cluster.SelfMember; if (self.Status != MemberStatus.Up) return Task.FromResult(HealthCheckResult.Unhealthy($"Node not Up (status: {self.Status}).")); var leader = cluster.State.Leader; if (leader != null && leader == self.Address) return Task.FromResult(HealthCheckResult.Healthy("Active node (cluster leader).")); return Task.FromResult(HealthCheckResult.Unhealthy("Standby node (not cluster leader).")); } }