示例#1
0
        public void Run()
        {
            do
            {
                if (UnacceptableMessageLimitReached())
                {
                    Channel.Dispose();
                    break;
                }

                s_logger.LogDebug("MessagePump: Receiving messages from channel {ChannelName} on thread # {ManagementThreadId}", Channel.Name, Thread.CurrentThread.ManagedThreadId);

                Message message = null;
                try
                {
                    message = Channel.Receive(TimeoutInMilliseconds);
                }
                catch (ChannelFailureException ex) when(ex.InnerException is BrokenCircuitException)
                {
                    s_logger.LogWarning("MessagePump: BrokenCircuitException messages from {ChannelName} on thread # {ManagementThreadId}", Channel.Name, Thread.CurrentThread.ManagedThreadId);
                    Task.Delay(ChannelFailureDelay).Wait();
                    continue;
                }
                catch (ChannelFailureException)
                {
                    s_logger.LogWarning("MessagePump: ChannelFailureException messages from {ChannelName} on thread # {ManagementThreadId}", Channel.Name, Thread.CurrentThread.ManagedThreadId);
                    Task.Delay(ChannelFailureDelay).Wait();
                    continue;
                }
                catch (Exception exception)
                {
                    s_logger.LogError(exception, "MessagePump: Exception receiving messages from {ChannelName} on thread # {ManagementThreadId}", Channel.Name, Thread.CurrentThread.ManagedThreadId);
                }

                if (message == null)
                {
                    Channel.Dispose();
                    throw new Exception("Could not receive message. Note that should return an MT_NONE from an empty queue on timeout");
                }

                // empty queue
                if (message.Header.MessageType == MessageType.MT_NONE)
                {
                    Task.Delay(EmptyChannelDelay).Wait();
                    continue;
                }

                // failed to parse a message from the incoming data
                if (message.Header.MessageType == MessageType.MT_UNACCEPTABLE)
                {
                    s_logger.LogWarning("MessagePump: Failed to parse a message from the incoming message with id {Id} from {ChannelName} on thread # {ManagementThreadId}", message.Id, Channel.Name, Thread.CurrentThread.ManagedThreadId);

                    IncrementUnacceptableMessageLimit();
                    AcknowledgeMessage(message);

                    continue;
                }

                // QUIT command
                if (message.Header.MessageType == MessageType.MT_QUIT)
                {
                    s_logger.LogInformation("MessagePump: Quit receiving messages from {ChannelName} on thread # {ManagementThreadId}", Channel.Name, Thread.CurrentThread.ManagedThreadId);
                    Channel.Dispose();
                    break;
                }

                // Serviceable message
                try
                {
                    var request = TranslateMessage(message);
                    CommandProcessorProvider.CreateScope();
                    DispatchRequest(message.Header, request);
                }
                catch (ConfigurationException configurationException)
                {
                    s_logger.LogCritical(configurationException,
                                         "MessagePump: Stopping receiving of messages from {ChannelName} on thread # {ManagementThreadId}",
                                         Channel.Name, Thread.CurrentThread.ManagedThreadId);

                    RejectMessage(message);
                    Channel.Dispose();
                    break;
                }
                catch (DeferMessageAction)
                {
                    if (RequeueMessage(message))
                    {
                        continue;
                    }
                }
                catch (AggregateException aggregateException)
                {
                    var(stop, requeue) = HandleProcessingException(aggregateException);

                    if (requeue)
                    {
                        if (RequeueMessage(message))
                        {
                            continue;
                        }
                    }

                    if (stop)
                    {
                        RejectMessage(message);
                        Channel.Dispose();
                        break;
                    }
                }
                catch (MessageMappingException messageMappingException)
                {
                    s_logger.LogWarning(messageMappingException,
                                        "MessagePump: Failed to map message '{Id}' from {ChannelName} on thread # {ManagementThreadId}",
                                        message.Id, Channel.Name, Thread.CurrentThread.ManagedThreadId);

                    IncrementUnacceptableMessageLimit();
                }
                catch (Exception e)
                {
                    s_logger.LogError(e,
                                      "MessagePump: Failed to dispatch message '{Id}' from {ChannelName} on thread # {ManagementThreadId}",
                                      message.Id, Channel.Name, Thread.CurrentThread.ManagedThreadId);
                }
                finally
                {
                    CommandProcessorProvider.ReleaseScope();
                }

                AcknowledgeMessage(message);
            } while (true);

            s_logger.LogInformation(
                "MessagePump0: Finished running message loop, no longer receiving messages from {ChannelName} on thread # {ManagementThreadId}",
                Channel.Name, Thread.CurrentThread.ManagedThreadId);
        }