public IEnumerable <Member> Apply(NetworkPartitionContext context) { var remaining = MembersWithRole(context.Remaining); var unreachable = MembersWithRole(context.Unreachable); if (remaining.Count < unreachable.Count) { return(context.Remaining); } if (remaining.Count > unreachable.Count) { return(context.Unreachable); } if (remaining.IsEmpty && unreachable.IsEmpty) { return(new Member[0]); } // if the parts are of equal size the part containing the node with the lowest address is kept. var oldest = remaining.Union(unreachable).First(); return(remaining.Contains(oldest) ? context.Unreachable : context.Remaining); }
public IEnumerable <Member> Apply(NetworkPartitionContext context) { var remainingCount = string.IsNullOrEmpty(Role) ? context.Remaining.Count : context.Remaining.Count(m => m.HasRole(Role)); return(remainingCount < QuorumSize ? context.Remaining : context.Unreachable); }
public IEnumerable <Member> Apply(NetworkPartitionContext context) { var isRefereeReachable = context.Remaining.Any(m => m.Address == Address); if (!isRefereeReachable) { return(context.Remaining); // referee is unreachable } else if (context.Remaining.Count < DownAllIfLessThanNodes) { return(context.Remaining.Union(context.Unreachable)); // referee is reachable but there are too few remaining nodes } else { return(context.Unreachable); } }
private void HandleStabilityReached() { if (Log.IsInfoEnabled && _unreachable.Any()) { Log.Info("A network partition detected - unreachable nodes: [{0}], remaining: [{1}]", string.Join(", ", _unreachable.Select(m => m.Address)), string.Join(", ", _reachable.Select(m => m.Address))); } var context = new NetworkPartitionContext(_unreachable, _reachable); var nodesToDown = _strategy.Apply(context).ToImmutableArray(); if (nodesToDown.Length > 0) { if (Log.IsInfoEnabled) { Log.Info("A network partition has been detected. {0} decided to down following nodes: [{1}]", _strategy, string.Join(", ", nodesToDown)); } foreach (var member in nodesToDown) { _cluster.Down(member.Address); } } }
public IEnumerable <Member> Apply(NetworkPartitionContext context) { var remaining = MembersWithRole(context.Remaining); var unreachable = MembersWithRole(context.Unreachable); if (remaining.IsEmpty && unreachable.IsEmpty) // prevent exception due to both lists being empty { return(new Member[0]); } var oldest = remaining.Union(unreachable).ToImmutableSortedSet(Member.AgeOrdering).First(); if (remaining.Contains(oldest)) { return(DownIfAlone && context.Remaining.Count == 1 && context.Unreachable.Count > 0 // oldest is current node, and it's alone, but not the only node in the cluster ? context.Remaining : context.Unreachable); } if (DownIfAlone && context.Unreachable.Count == 1) // oldest is unreachable, but it's alone { return(context.Unreachable); } return(context.Remaining); }