Beispiel #1
0
        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);
        }
Beispiel #2
0
        public void DownPeer(IGossipPeer peer)
        {
            _remotePeers.AddOrUpdate(peer.Id, peer, (id, p) =>
            {
                p.State = peer.State;
                return(p);
            });

            PeerDown?.Invoke(this, new GossipPeerEventArgs(peer));
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
 public HelloRequest(IGossipPeer peer)
     : base(peer)
 {
 }
Beispiel #5
0
 public void AddPeer(IGossipPeer peer)
 {
     _remotePeers.TryAdd(peer.Id, peer);
     NewPeerFound?.Invoke(this, new GossipPeerEventArgs(peer));
 }
Beispiel #6
0
 public GossipPeerEventArgs(IGossipPeer peer)
 {
     _peer = peer;
 }
 public HeartbeatRequest(IGossipPeer peer)
 {
     Peer    = peer;
     Members = new List <IGossipPeer>();
 }
Beispiel #8
0
        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();
        }