/// <summary> /// The set of Akka.Cluster nodes designated for receiving heartbeats from this node. /// </summary> /// <param name="sender">The node sending heartbeats.</param> /// <returns>An organized ring of unique nodes.</returns> public IImmutableSet <UniqueAddress> Receivers(UniqueAddress sender) { if (_useAllAsReceivers) { return(NodeRing.Remove(sender)); } else { // Pick nodes from the iterator until n nodes that are not unreachable have been selected. // Intermediate unreachable nodes up to `monitoredByNrOfMembers` are also included in the result. // The reason for not limiting it to strictly monitoredByNrOfMembers is that the leader must // be able to continue its duties (e.g. removal of downed nodes) when many nodes are shutdown // at the same time and nobody in the remaining cluster is monitoring some of the shutdown nodes. (int, ImmutableSortedSet <UniqueAddress>) Take(int n, IEnumerator <UniqueAddress> iter, ImmutableSortedSet <UniqueAddress> acc, ImmutableHashSet <UniqueAddress> unreachable, int monitoredByNumberOfNodes) { while (true) { if (iter.MoveNext() == false || n == 0) { iter.Dispose(); // dispose enumerator return(n, acc); } else { var next = iter.Current; var isUnreachable = unreachable.Contains(next); if (isUnreachable && acc.Count >= monitoredByNumberOfNodes) { } else if (isUnreachable) { acc = acc.Add(next); } else { n = n - 1; acc = acc.Add(next); } } } } var(remaining, slice1) = Take(MonitoredByNumberOfNodes, NodeRing.From(sender).Skip(1).GetEnumerator(), ImmutableSortedSet <UniqueAddress> .Empty, Unreachable, MonitoredByNumberOfNodes); IImmutableSet <UniqueAddress> slice = remaining == 0 ? slice1 // or, wrap-around : Take(remaining, NodeRing.TakeWhile(x => x != sender).GetEnumerator(), slice1, Unreachable, MonitoredByNumberOfNodes).Item2; return(slice); } }
public ImmutableHashSet <UniqueAddress> Receivers(UniqueAddress sender) { if (_useAllAsReceivers) { return(NodeRing.Remove(sender).ToImmutableHashSet()); } var slice = NodeRing.From(sender).Skip(1).Take(MonitoredByNumberOfNodes).ToList(); //grab members furthest from this peer if (slice.Count < MonitoredByNumberOfNodes) { slice = slice.Concat(NodeRing.Take(MonitoredByNumberOfNodes - slice.Count)).ToList(); } return(slice.ToImmutableHashSet()); }