Exemple #1
0
 private void PushToMemberListeners(MemberEvent memberEvent)
 {
     foreach (var listener in _options.MemberListeners)
     {
         listener.MemberUpdatedCallback(memberEvent).ConfigureAwait(false);
     }
 }
Exemple #2
0
        internal static MemberEvent ReadFrom(IPEndPoint senderGossipEndPoint, DateTime receivedDateTime, Stream stream, bool isSender = false)
        {
            if (stream.Position >= stream.Length)
            {
                return(null);
            }

            var memberEvent = new MemberEvent
            {
                SenderGossipEndPoint = senderGossipEndPoint,
                ReceivedDateTime     = receivedDateTime,

                IP         = isSender ? senderGossipEndPoint.Address : stream.ReadIPAddress(),
                GossipPort = isSender ? (ushort)senderGossipEndPoint.Port : stream.ReadPort(),
                State      = isSender ? MemberState.Alive : stream.ReadMemberState(),
                Generation = (byte)stream.ReadByte(),
            };

            if (memberEvent.State == MemberState.Alive)
            {
                memberEvent.Service     = (byte)stream.ReadByte();
                memberEvent.ServicePort = stream.ReadPort();
            }

            return(memberEvent);
        }
Exemple #3
0
        private void UpdateMembers(IPEndPoint senderGossipEndPoint, DateTime receivedDateTime, Stream stream)
        {
            // read sender
            var memberEvent = MemberEvent.ReadFrom(senderGossipEndPoint, receivedDateTime, stream, true);

            // handle ourself
            var selfClaimedState      = stream.ReadMemberState();
            var selfClaimedGeneration = (byte)stream.ReadByte();

            if (_self.IsLaterGeneration(selfClaimedGeneration) ||
                (selfClaimedState != MemberState.Alive && selfClaimedGeneration == _self.Generation))
            {
                PushToMemberListeners(new MemberEvent(senderGossipEndPoint, receivedDateTime, _self.IP, _self.GossipPort, selfClaimedState, selfClaimedGeneration));

                _self.Generation = (byte)(selfClaimedGeneration + 1);
                _logger.LogInformation("Gossip.Mesh received a claim about self, state:{state} generation:{generation}. Raising generation to {generation}", selfClaimedState, selfClaimedGeneration, _self.Generation);

                PushToMemberListeners(new MemberEvent(_self.GossipEndPoint, DateTime.UtcNow, _self));
            }

            // handler sender and everyone else
            while (memberEvent != null)
            {
                lock (_locker)
                {
                    if (_members.TryGetValue(memberEvent.GossipEndPoint, out var member) &&
                        (member.IsLaterGeneration(memberEvent.Generation) ||
                         (member.Generation == memberEvent.Generation && member.IsStateSuperseded(memberEvent.State))))
                    {
                        // stops state escalation
                        if (memberEvent.State == MemberState.Alive && memberEvent.Generation > member.Generation)
                        {
                            RemoveAwaitingAck(memberEvent.GossipEndPoint);
                        }

                        member.Update(memberEvent);
                        _logger.LogInformation("Gossip.Mesh member state changed {member}", member);

                        PushToMemberListeners(memberEvent);
                    }

                    else if (member == null)
                    {
                        member = new Member(memberEvent);
                        _members.Add(member.GossipEndPoint, member);
                        _logger.LogInformation("Gossip.Mesh member added {member}", member);

                        PushToMemberListeners(memberEvent);
                    }

                    if (member.State != MemberState.Alive)
                    {
                        AddAwaitingAck(member.GossipEndPoint);
                    }
                }

                memberEvent = MemberEvent.ReadFrom(senderGossipEndPoint, receivedDateTime, stream);
            }
        }
Exemple #4
0
 internal Member(MemberEvent memberEvent)
 {
     IP          = memberEvent.IP;
     GossipPort  = memberEvent.GossipPort;
     State       = memberEvent.State;
     Generation  = memberEvent.Generation;
     Service     = memberEvent.Service;
     ServicePort = memberEvent.ServicePort;
 }
Exemple #5
0
 public bool Equal(MemberEvent memberEvent)
 {
     return(memberEvent != null &&
            IP.Equals(memberEvent.IP) &&
            GossipPort == memberEvent.GossipPort &&
            State == memberEvent.State &&
            Generation == memberEvent.Generation &&
            Service == memberEvent.Service &&
            ServicePort == memberEvent.ServicePort);
 }
Exemple #6
0
        internal void Update(MemberEvent memberEvent)
        {
            State      = memberEvent.State;
            Generation = memberEvent.Generation;

            if (memberEvent.State == MemberState.Alive)
            {
                Service     = memberEvent.Service;
                ServicePort = memberEvent.ServicePort;
            }

            Interlocked.Exchange(ref _gossipCounter, 0);
        }
Exemple #7
0
        private void UpdateMemberState(IPEndPoint gossipEndPoint, MemberState memberState)
        {
            lock (_locker)
            {
                if (_members.TryGetValue(gossipEndPoint, out var member) && member.State < memberState)
                {
                    member.Update(memberState);
                    _logger.LogInformation("Gossip.Mesh {memberState} member {member}", memberState.ToString().ToLower(), member);

                    var memberEvent = new MemberEvent(_self.GossipEndPoint, DateTime.UtcNow, member);
                    PushToMemberListeners(memberEvent);
                }
            }
        }
Exemple #8
0
 public bool NotEqual(MemberEvent memberEvent)
 {
     return(!Equal(memberEvent));
 }