private void RelayPing(MessageBase message)
        {
            var m = message as PingReqMessage;

            if (m.CorrelationId.HasValue)
            {
                _logger.LogInformation(
                    $"Relaying PING {m.SourceNode} -> {m.SubjectNode}");

                CorrelatedMessages.TryAdd(m.CorrelationId.Value, m);
                _swimProtocolProvider.SendMessage(m.SubjectNode, new PingMessage(m.CorrelationId.Value)
                {
                    SourceNode = _swimProtocolProvider.Node
                });
            }
        }
Exemplo n.º 2
0
        private void HandleMessage(MessageBase message)
        {
            Debug.WriteLine($"Processing {message.MessageType} Message from {message.SourceNode?.Endpoint ?? "unidentified node"}");
            Logger.LogInformation($"Processing {message.MessageType} Message from {message.SourceNode?.Endpoint ?? "unidentified node"}");

            try
            {
                switch (message.MessageType)
                {
                case MessageType.Composite:
                {
                    var cm = message as CompositeMessage;

                    if (cm.Messages != null)
                    {
                        foreach (var em in cm.Messages)
                        {
                            HandleMessage(em);
                        }
                    }
                }

                break;

                case MessageType.Alive:
                {
                    lock (_nodesLock)
                    {
                        if (!Nodes.Any(x => x == message.SourceNode))
                        {
                            AddNode(message.SourceNode);
                        }
                    }

                    AddBroadcastMessage(message);
                }

                break;

                case MessageType.Dead:
                {
                    lock (_nodesLock)
                    {
                        if (Nodes.Any(x => x == message.SourceNode))
                        {
                            RemoveNode(message.SourceNode);
                        }
                    }

                    AddBroadcastMessage(message);
                }

                break;

                case MessageType.Ping:
                {
                    lock (_nodesLock)
                    {
                        if (!Nodes.Any(x => x == message.SourceNode))
                        {
                            AddNode(message.SourceNode);
                        }
                    }

                    if (message.SourceNode != null && ProtocolProvider?.Node?.Endpoint != null)
                    {
                        ProtocolProvider.SendMessage(message.SourceNode,
                                                     new AckMessage(message.CorrelationId, ProtocolProvider.Node));
                    }
                }

                break;

                case MessageType.Ack:
                {
                    if (message.SourceNode == ActiveNode)
                    {
                        lock (_receivedAckLock)
                        {
                            ReceivedAck = true;
                        }
                    }

                    if (message.CorrelationId.HasValue)
                    {
                        MessageBase ms = null;

                        //  Send message back to originating node.
                        if (CorrelatedMessages.TryRemove(message.CorrelationId.Value, out ms))
                        {
                            var cm = ms as PingReqMessage;
                            ProtocolProvider.SendMessage(cm.SourceNode, message);
                        }
                    }
                }

                break;

                case MessageType.PingReq:
                {
                    var m = message as PingReqMessage;

                    if (m.CorrelationId.HasValue)
                    {
                        CorrelatedMessages.TryAdd(m.CorrelationId.Value, m);
                    }

                    ProtocolProvider.SendMessage(m.Endpoint, new PingMessage(m.CorrelationId.Value)
                        {
                            SourceNode = ProtocolProvider.Node
                        });
                }

                break;

                default:
                    Debug.WriteLine($"Unknown message type {message.MessageType}, skipping...");
                    Logger.LogWarning($"Unknown message type {message.MessageType}, skipping...");

                    break;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine($"{e.ToString()}: {e.StackTrace}");
                Logger.LogError(e, string.Empty);
            }
        }
        private void _swimProtocolProvider_ReceivedMessage(object sender, ReceivedMessageEventArgs e)
        {
            try
            {
                foreach (var signedMessage in e.CompositeMessage.Messages)
                {
                    if (!signedMessage.IsValid())
                    {
                        _logger.LogError("Signature check failed!");
                        continue;
                    }

                    var messageType = signedMessage.Message.MessageType;
                    var message     = signedMessage.Message;

                    if (message.IsValid)
                    {
                        switch (messageType)
                        {
                        case MessageType.Alive:
                        {
                            if (AddBroadcastMessage(signedMessage))
                            {
                                var casted = message as AliveMessage;

                                if (casted != null)
                                {
                                    _logger.LogInformation(
                                        $"{signedMessage.Message.SourceNode} marked {casted.SubjectNode} ALIVE");
                                    AddNode(casted.SubjectNode);
                                }
                            }
                        }
                        break;

                        case MessageType.Dead:
                        {
                            if (AddBroadcastMessage(signedMessage))
                            {
                                var casted = message as DeadMessage;

                                if (casted != null)
                                {
                                    _logger.LogInformation(
                                        $"{signedMessage.Message.SourceNode} marked {casted.SubjectNode} SUSPECT");
                                    RemoveNode(casted.SubjectNode);
                                }
                            }
                        }
                        break;

                        case MessageType.Ping:
                        {
                            SendAck(message);
                            AddNode(message.SourceNode);
                        }
                        break;

                        case MessageType.PingReq:
                        {
                            RelayPing(message);
                        }
                        break;

                        case MessageType.Suspect:
                        {
                            if (AddBroadcastMessage(signedMessage))
                            {
                                var casted = message as SuspectMessage;
                                _logger.LogInformation($"{signedMessage.Message.SourceNode} marked {casted.SubjectNode} SUSPECT");
                                MarkNodeSuspicious(casted.SubjectNode);
                            }
                        }
                        break;

                        case MessageType.Ack:
                        {
                            HandleAck(message);
                            AddNode(message.SourceNode);

                            MessageBase ms = null;

                            //  Send swimMessage back to originating node.
                            if (message.CorrelationId.HasValue && CorrelatedMessages.TryRemove(message.CorrelationId.Value, out ms))
                            {
                                var cm = ms as PingReqMessage;
                                _logger.LogInformation(
                                    $"Relaying ACK {message.SourceNode} -> {cm.SourceNode}");
                                _swimProtocolProvider.SendMessage(cm.SourceNode, message);
                            }
                        }

                        break;
                        }
                    }

                    _logger.LogInformation($"Received: {JsonConvert.SerializeObject(message)}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Exception during receive message");
            }
        }