Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.Host/Health/ClusterActivityEvaluator.cs
T

41 lines
2.2 KiB
C#

using Akka.Cluster;
namespace ZB.MOM.WW.ScadaBridge.Host.Health;
/// <summary>
/// THE single definition of "active node" (review 01 [High]): a node is active
/// when it is the OLDEST Up member (optionally within a role scope) — i.e. the
/// member the ClusterSingletonManager places singletons on. Cluster LEADERSHIP
/// (lowest address) is an Akka-internal concept that diverges from singleton
/// placement permanently once the original first node restarts and rejoins;
/// every product-level active/standby decision must use this evaluator, never
/// cluster.State.Leader.
/// </summary>
public static class ClusterActivityEvaluator
{
/// <summary>True when self is Up and no other Up member (in the role scope) is older.
/// Delegates to the shared <see cref="Communication.ClusterState.ActiveNodeEvaluator"/> —
/// one implementation for the delivery gate, the resync authority checks, and the
/// heartbeat IsActive stamp (review 02 round 2, N1).</summary>
/// <param name="cluster">The Akka cluster to evaluate.</param>
/// <param name="role">Optional role scope; when set, only members with this role are considered.</param>
/// <returns><c>true</c> when self is Up and the oldest Up member in the role scope.</returns>
public static bool SelfIsOldest(Cluster cluster, string? role = null) =>
Communication.ClusterState.ActiveNodeEvaluator.SelfIsOldestUp(cluster, role);
/// <summary>The oldest Up member in the role scope, or null while none is Up. Used for Primary/Standby labelling.</summary>
/// <param name="cluster">The Akka cluster to evaluate.</param>
/// <param name="role">Optional role scope; when set, only members with this role are considered.</param>
/// <returns>The oldest Up member in the role scope, or null when none is Up.</returns>
public static Member? OldestUpMember(Cluster cluster, string? role = null)
{
Member? oldest = null;
foreach (var m in cluster.State.Members.Where(m => m.Status == MemberStatus.Up))
{
if (role != null && !m.HasRole(role)) continue;
if (oldest == null || m.IsOlderThan(oldest)) oldest = m;
}
return oldest;
}
}