/// <summary> /// TBD /// </summary> /// <param name="sender">TBD</param> /// <returns>TBD</returns> public ImmutableHashSet <UniqueAddress> Receivers(UniqueAddress sender) { if (_useAllAsReceivers) { return(NodeRing().Remove(sender).ToImmutableHashSet()); } 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. Func <int, IEnumerator <UniqueAddress>, ImmutableSortedSet <UniqueAddress>, Tuple <int, ImmutableSortedSet <UniqueAddress> > > take = null; take = (n, iter, acc) => { if (iter.MoveNext() == false || n == 0) { return(Tuple.Create(n, acc)); } else { UniqueAddress next = iter.Current; var isUnreachable = Unreachable.Contains(next); if (isUnreachable && acc.Count >= MonitoredByNumberOfNodes) { return(take(n, iter, acc)); // skip the unreachable, since we have already picked `MonitoredByNumberOfNodes` } else if (isUnreachable) { return(take(n, iter, acc.Add(next))); // include the unreachable, but don't count it } else { return(take(n - 1, iter, acc.Add(next))); // include the reachable } } }; var tuple = take(MonitoredByNumberOfNodes, NodeRing().From(sender).Skip(1).GetEnumerator(), ImmutableSortedSet <UniqueAddress> .Empty); var remaining = tuple.Item1; var slice1 = tuple.Item2; IImmutableSet <UniqueAddress> slice = remaining == 0 ? slice1 : take(remaining, NodeRing().Until(sender).Where(c => !c.Equals(sender)).GetEnumerator(), slice1).Item2; return(slice.ToImmutableHashSet()); } }
public ClusterHeartbeatSenderState HeartbeatRsp(UniqueAddress from) { if (ActiveReceivers.Contains(from)) { FailureDetector.Heartbeat(from.Address); if (Unreachable.Contains(from)) { //back from unreachable, ok to stop heartbeating to it if (!Ring.MyReceivers.Value.Contains(from)) { FailureDetector.Remove(from.Address); } return(Copy(unreachable: Unreachable.Remove(from))); } return(this); } return(this); }