fix(cluster): gossiped-role predicates compare case-insensitively — a miscased peer no longer un-elects the Primary
This commit is contained in:
@@ -23,8 +23,13 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
|
||||
private readonly string? _clusterRole;
|
||||
private readonly string? _clusterId;
|
||||
private readonly object _lock = new();
|
||||
private readonly Dictionary<string, Member?> _roleLeaders = new(StringComparer.Ordinal);
|
||||
private readonly Dictionary<string, HashSet<Member>> _membersByRole = new(StringComparer.Ordinal);
|
||||
// R3-04 (01/C-9, census row 17): OrdinalIgnoreCase — Akka compares gossiped role names ordinally,
|
||||
// so a PEER running an older build can still gossip a miscased plain role during a rolling
|
||||
// upgrade. Keying these by the exact-cased role string would leave MembersWithRole("driver") and
|
||||
// RoleLeader("driver") blind to a peer that gossips "Driver", the same class of gap #532 closed
|
||||
// for _localRoles above.
|
||||
private readonly Dictionary<string, Member?> _roleLeaders = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, HashSet<Member>> _membersByRole = new(StringComparer.OrdinalIgnoreCase);
|
||||
private IActorRef? _subscriber;
|
||||
|
||||
/// <summary>Initializes a new instance of the ClusterRoleInfo class.</summary>
|
||||
|
||||
@@ -153,4 +153,15 @@ public static class RoleParser
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
/// <summary>True when a GOSSIPED role list carries <paramref name="role"/>, compared
|
||||
/// case-insensitively. Akka compares role names ordinally and a PEER may be running an older
|
||||
/// build that gossips a verbatim 'Driver' (archreview 01/C-9), so every predicate over
|
||||
/// <c>Member.Roles</c> goes through here rather than <c>List.Contains</c>.</summary>
|
||||
/// <param name="gossipedRoles">The gossiped role list (e.g. <c>Member.Roles</c>).</param>
|
||||
/// <param name="role">The role to test for.</param>
|
||||
/// <returns>True when <paramref name="role"/> is present, case-insensitively.</returns>
|
||||
public static bool GossipedRolesHave(IEnumerable<string>? gossipedRoles, string role) =>
|
||||
gossipedRoles is not null
|
||||
&& gossipedRoles.Any(r => string.Equals(r, role, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user