32 lines
1.5 KiB
C#
32 lines
1.5 KiB
C#
using Akka.Actor;
|
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.Host.Health;
|
|
|
|
/// <summary>
|
|
/// /health/active check: Healthy only on the oldest Up member — the node that
|
|
/// hosts the cluster singletons. Replaces the shared package's leader-based
|
|
/// ActiveNodeHealthCheck (review 01 [High]): leadership is address-ordered and
|
|
/// diverges from singleton placement after a restart, and during a partition
|
|
/// BOTH nodes compute themselves leader, so Traefik served both. Oldest-member
|
|
/// semantics keep exactly one active node through a partition (the non-oldest
|
|
/// side still sees the old oldest member until SBR resolves membership).
|
|
/// </summary>
|
|
public sealed class OldestNodeActiveHealthCheck : IHealthCheck
|
|
{
|
|
private readonly ActorSystem _system;
|
|
|
|
/// <summary>Initializes a new <see cref="OldestNodeActiveHealthCheck"/> bound to the running actor system.</summary>
|
|
/// <param name="system">The live cluster actor system.</param>
|
|
public OldestNodeActiveHealthCheck(ActorSystem system) => _system = system;
|
|
|
|
/// <inheritdoc />
|
|
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken ct = default)
|
|
{
|
|
var cluster = Akka.Cluster.Cluster.Get(_system);
|
|
return Task.FromResult(ClusterActivityEvaluator.SelfIsOldest(cluster)
|
|
? HealthCheckResult.Healthy("oldest Up member (singleton host)")
|
|
: HealthCheckResult.Unhealthy("not the oldest Up member (standby)"));
|
|
}
|
|
}
|