Exemple #1
0
        /// <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());
            }
        }
Exemple #2
0
 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);
 }