fix(cluster): gossiped-role predicates compare case-insensitively — a miscased peer no longer un-elects the Primary

This commit is contained in:
Joseph Doherty
2026-08-20 10:04:16 -04:00
parent bcec88ef70
commit e46c1db5e5
12 changed files with 370 additions and 11 deletions
@@ -1,6 +1,7 @@
using Akka.Actor;
using Akka.Cluster.Tools.PublishSubscribe;
using Akka.Event;
using ZB.MOM.WW.OtOpcUa.Cluster;
using ZB.MOM.WW.OtOpcUa.Commons.Messages.Alerts;
using ZB.MOM.WW.OtOpcUa.Commons.Messages.Redundancy;
using ZB.MOM.WW.OtOpcUa.Commons.Observability;
@@ -516,8 +517,11 @@ public sealed class ScriptedAlarmHostActor : ReceiveActor
if (_driverMemberCountProvider is not null) return _driverMemberCountProvider();
try
{
// R3-04 (01/C-9): GossipedRolesHave, not ordinal Contains — a peer gossiping a miscased
// 'Driver' (rolling-upgrade window) must still count toward the alerts-emit gate.
return Akka.Cluster.Cluster.Get(Context.System).State.Members
.Count(m => m.Status == Akka.Cluster.MemberStatus.Up && m.Roles.Contains(ServiceCollectionExtensions.DriverRole));
.Count(m => m.Status == Akka.Cluster.MemberStatus.Up
&& RoleParser.GossipedRolesHave(m.Roles, ServiceCollectionExtensions.DriverRole));
}
catch (Exception)
{