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); }