41 lines
2.2 KiB
C#
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;
|
|
}
|
|
}
|