protected IGossipPeer SelectNeighbor(IList <IGossipPeer> memberList) { IGossipPeer peer = null; if (memberList.Count > 0) { int tryCount = 0; Random random = new Random(); do { int randomNeighborIndex = random.Next(0, memberList.Count - 1); peer = memberList[randomNeighborIndex]; if (++tryCount == 5) { peer = null; break; } } while (peer != null && peer.Id == _gossipNode.GossipPeer.Id); } else { Logger.Debug("I am alone."); } return(peer); }
public void DownPeer(IGossipPeer peer) { _remotePeers.AddOrUpdate(peer.Id, peer, (id, p) => { p.State = peer.State; return(p); }); PeerDown?.Invoke(this, new GossipPeerEventArgs(peer)); }
protected bool MergeLists(IGossipPeer senderPeer, IList <IGossipPeer> remoteList) { var needReply = false; foreach (GossipPeer remotePeer in remoteList) { if (remotePeer.Id == _gossipNode.GossipPeer.Id) { continue; } var peer = _gossipNode.RemotePeers.FirstOrDefault(p => p.Id == remotePeer.Id); if (peer != null) { if (remotePeer.Heartbeat > peer.Heartbeat) { peer.Heartbeat = remotePeer.Heartbeat; if (peer.State == GossipPeerState.Online && remotePeer.State == GossipPeerState.Offline) { _gossipNode.DownPeer(remotePeer); } else if (peer.State == GossipPeerState.Offline && remotePeer.State == GossipPeerState.Online) { _gossipNode.WakeUpPeer(remotePeer); } } else { needReply = true; } } else { _gossipNode.AddPeer(remotePeer); } } return(needReply); }
public HelloRequest(IGossipPeer peer) : base(peer) { }
public void AddPeer(IGossipPeer peer) { _remotePeers.TryAdd(peer.Id, peer); NewPeerFound?.Invoke(this, new GossipPeerEventArgs(peer)); }
public GossipPeerEventArgs(IGossipPeer peer) { _peer = peer; }
public HeartbeatRequest(IGossipPeer peer) { Peer = peer; Members = new List <IGossipPeer>(); }
public GossipManager(GossipNode gossipNode) { _gossipNode = gossipNode; _cts = new CancellationTokenSource(); _currentStateExtension = new CurrentStateExtension(); _requests = new ConcurrentDictionary <string, BaseMessage>(); _helloTimer = new Timer(new TimerCallback(HelloTimerHandle)); _heartbeatTimer = new Timer(new TimerCallback(HeartbeatTimerHandle)); _fsm = new AsyncPassiveStateMachine <NodeState, GossipEvent>("GossipManager"); _fsm.AddExtension(new ConsoleLogExtension()); _fsm.AddExtension(_currentStateExtension); _fsm.Initialize(NodeState.Initialized); _fsm.In(NodeState.Initialized) .On(GossipEvent.HelloSend) .Goto(NodeState.HelloSent) .Execute(async() => { // set hello timer await SendHello(); }); _fsm.In(NodeState.HelloSent) .On(GossipEvent.HelloAnswer) .Goto(NodeState.Infected) .Execute <HelloResponse>((msg) => { ReceiveHelloAnswer(msg); }) .On(GossipEvent.HelloExpired) .Goto(NodeState.Initialized) .Execute(async() => { // hello timer re-set await SendHello(); }); _fsm.In(NodeState.Infected) .On(GossipEvent.HeartbeatExpired) .Goto(NodeState.Susceptible) .Execute(async() => { await SendHeartbeat(); }) .On(GossipEvent.HeartbeatAnswer) .Goto(NodeState.Infected) .Execute <HeartbeatResponse>((msg) => { IGossipPeer senderPeer = msg.Members?.FirstOrDefault(); MergeLists(senderPeer, msg.Members); }); _fsm.In(NodeState.Infected) .On(GossipEvent.HelloReceive) .Execute <HelloRequest>(async(msg) => { await SendHelloAnswer(msg); }); _fsm.In(NodeState.Susceptible) .On(GossipEvent.HelloReceive) .Execute <HelloRequest>(async(msg) => { await SendHelloAnswer(msg); }) .On(GossipEvent.HeartbeatReceive) .If <HeartbeatRequest>((msg) => { return(_gossipNode.GossipPeer.Heartbeat < msg.Peer.Heartbeat); }) .Goto(NodeState.Infected) .Execute <HeartbeatRequest>(async(msg) => { await ReceiveHeartbeat(msg); }) .On(GossipEvent.HeartbeatAnswer) .If <HeartbeatResponse>((msg) => { return(msg.Members[0].Heartbeat > _gossipNode.GossipPeer.Heartbeat); }).Goto(NodeState.Infected); _fsm.Start(); }