/// <summary> /// TBD /// </summary> /// <param name="message">TBD</param> protected override void OnReceive(object message) { switch (message) { case ClusterEvent.CurrentClusterState state: _clusterNodes = state.Members.Select(m => m.Address).Where(a => a != _cluster.SelfAddress).ToImmutableHashSet(); foreach (var node in _clusterNodes) { TakeOverResponsibility(node); } Unreachable.ExceptWith(_clusterNodes); return; case ClusterEvent.MemberUp up: MemberUp(up.Member); return; case ClusterEvent.MemberWeaklyUp weaklyUp: MemberUp(weaklyUp.Member); return; case ClusterEvent.MemberRemoved removed: MemberRemoved(removed.Member, removed.PreviousStatus); return; case ClusterEvent.IMemberEvent _: return; // not interesting } base.OnReceive(message); }
private void MemberUp(Member member) { if (!member.Address.Equals(_cluster.SelfAddress)) { _clusterNodes = _clusterNodes.Add(member.Address); TakeOverResponsibility(member.Address); Unreachable.Remove(member.Address); } }
protected override void OnReceive(object message) { var watchRemote = message as WatchRemote; if (watchRemote != null && _clusterNodes.Contains(watchRemote.Watchee.Path.Address)) { return; // cluster managed node, don't propagate to super; } var state = message as ClusterEvent.CurrentClusterState; if (state != null) { _clusterNodes = state.Members.Select(m => m.Address).Where(a => a != _cluster.SelfAddress).ToImmutableHashSet(); foreach (var node in _clusterNodes) { TakeOverResponsibility(node); } Unreachable.ExceptWith(_clusterNodes); return; } var memberUp = message as ClusterEvent.MemberUp; if (memberUp != null) { if (memberUp.Member.Address != _cluster.SelfAddress) { _clusterNodes = _clusterNodes.Add(memberUp.Member.Address); TakeOverResponsibility(memberUp.Member.Address); Unreachable.Remove(memberUp.Member.Address); } return; } var memberRemoved = message as ClusterEvent.MemberRemoved; if (memberRemoved != null) { if (memberRemoved.Member.Address != _cluster.SelfAddress) { _clusterNodes = _clusterNodes.Remove(memberRemoved.Member.Address); if (memberRemoved.PreviousStatus == MemberStatus.Down) { Quarantine(memberRemoved.Member.Address, memberRemoved.Member.UniqueAddress.Uid); } PublishAddressTerminated(memberRemoved.Member.Address); } return; } if (message is ClusterEvent.IMemberEvent) { return; // not interesting } base.OnReceive(message); }
/// <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); }
/// <summary> /// TBD /// </summary> /// <param name="message">TBD</param> protected override void OnReceive(object message) { var state = message as ClusterEvent.CurrentClusterState; if (state != null) { _clusterNodes = state.Members.Select(m => m.Address).Where(a => a != _cluster.SelfAddress).ToImmutableHashSet(); foreach (var node in _clusterNodes) { TakeOverResponsibility(node); } Unreachable.ExceptWith(_clusterNodes); return; } var memberUp = message as ClusterEvent.MemberUp; if (memberUp != null) { MemberUp(memberUp.Member); return; } var memberRemoved = message as ClusterEvent.MemberRemoved; if (memberRemoved != null) { MemberRemoved(memberRemoved.Member, memberRemoved.PreviousStatus); return; } if (message is ClusterEvent.IMemberEvent) { return; // not interesting } base.OnReceive(message); }