private void PushToMemberListeners(MemberEvent memberEvent) { foreach (var listener in _options.MemberListeners) { listener.MemberUpdatedCallback(memberEvent).ConfigureAwait(false); } }
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); }
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); } }
internal Member(MemberEvent memberEvent) { IP = memberEvent.IP; GossipPort = memberEvent.GossipPort; State = memberEvent.State; Generation = memberEvent.Generation; Service = memberEvent.Service; ServicePort = memberEvent.ServicePort; }
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); }
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); }
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); } } }
public bool NotEqual(MemberEvent memberEvent) { return(!Equal(memberEvent)); }