private void EncodeAlive(AliveMessage message, BinaryWriter writer) { writer.Write(message.Name); var ipAddressBytes = message.IPEndPoint.Address.GetAddressBytes(); writer.Write(ipAddressBytes.Length); writer.Write(ipAddressBytes); writer.Write(message.IPEndPoint.Port); writer.Write(message.Metadata == null ? 0 : message.Metadata.Length); if (message.Metadata != null && message.Metadata.Length > 0) { writer.Write(message.Metadata); } writer.Write(message.Incarnation); }
private void HandleDead(IPEndPoint remoteEndPoint, DeadMessage message) { TrackedGossipNode node; lock(_lock) { if (!_nodes.TryGetValue(message.Name, out node)) return; if (message.Incarnation < node.Incarnation) return; if (node.State == GossipNodeState.Dead) return; if (node.Name == _configuration.Name) { // we need to rebut this if we aren't leaving if (_leaveEvent == null) { int incarnation = GetNextIncarnationNumber(); while ((incarnation = GetNextIncarnationNumber()) <= message.Incarnation) ; var alive = new AliveMessage( _configuration.Name, _configuration.LocalEndPoint, _configuration.Metadata, incarnation); _messagePump.Broadcast(alive, null); node.Incarnation = incarnation; return; } } node.Incarnation = message.Incarnation; node.State = GossipNodeState.Dead; node.UpdatedAtUtc = DateTime.UtcNow; _nodes.Remove(node); } // leave event will not be null if we are leaving. // therefore, we will wait in the shutdown method // until this broadcast goes out. _messagePump.Broadcast(message, _leaveEvent); if(NodeLeft != null) { NodeLeft(node); } }
private void HandleAlive(IPEndPoint remoteEndPoint, AliveMessage message) { TrackedGossipNode node; GossipNodeState oldState; lock (_lock) { if (!_nodes.TryGetValue(message.Name, out node)) { node = new TrackedGossipNode(message.Name, message.IPEndPoint, message.Metadata) { Incarnation = int.MinValue, State = GossipNodeState.Dead, UpdatedAtUtc = DateTime.MinValue }; if (_nodes.Count > 0) { int randomIndex = _random.Next(0, _nodes.Count - 1); var temp = _nodes[randomIndex]; _nodes[randomIndex] = node; _nodes.Add(temp); } else { _nodes.Add(node); } } if (!node.IPEndPoint.Equals(message.IPEndPoint)) { _configuration.Logger.Error("Conflicting endpoints for {Name}. Mine: {MyEndPoint} Theirs: {TheirEndPoint}", node.Name, node.IPEndPoint, message.IPEndPoint); return; } if (node.Incarnation >= message.Incarnation) { _configuration.Logger.Verbose("Received old incarnation alive request for {Name}. Mine: {MyIncarnation} Theirs: {TheirIncarnation}", node.Name, node.Incarnation, message.Incarnation); return; } oldState = node.State; node.State = GossipNodeState.Alive; node.Incarnation = message.Incarnation; node.UpdatedAtUtc = DateTime.UtcNow; } _messagePump.Broadcast(message, null); if (oldState == GossipNodeState.Dead) { if (NodeJoined != null) { NodeJoined(node); } } }
private void EncodeAlive(AliveMessage message, BinaryWriter writer) { writer.Write(message.Name); var ipAddressBytes = message.IPEndPoint.Address.GetAddressBytes(); writer.Write(ipAddressBytes.Length); writer.Write(ipAddressBytes); writer.Write(message.IPEndPoint.Port); writer.Write(message.Metadata == null ? 0 : message.Metadata.Length); if(message.Metadata != null && message.Metadata.Length > 0) { writer.Write(message.Metadata); } writer.Write(message.Incarnation); }