private void ReceiveAndProcessMessage(IPluginQueue queue) { _needToAbort = false; _messageId = string.Empty; try { if (IsTransactional) { new TransactionWrapper().RunInTransaction(ReceiveFromQueue, queue, IsolationLevel, TransactionTimeout); } else { ReceiveFromQueue(queue); } ClearFailuresForMessage(_messageId); } catch (AbortHandlingCurrentMessageException) { //in case AbortHandlingCurrentMessage was called return; } catch (Exception e) { Logger.Warn("Failed to process message.", e); if (IsTransactional) { IncrementFailuresForMessage(_messageId); } OnFailedMessageProcessing(); } }
/// <summary> /// Moves the given message to the configured error queue. /// </summary> /// <param name="m"></param> /// <param name="queue"></param> protected void MoveToErrorQueue(Message m, IPluginQueue queue) { m.Label = m.Label + string.Format("<{0}>{1}</{0}><{2}>{3}<{2}>", FAILEDQUEUE, queue.IndependentAddressForQueue, ORIGINALID, m.Id); if (errorQueue != null) { errorQueue.Send(m, MessageQueueTransactionType.Single); } }
[DebuggerNonUserCode] // so that exceptions don't interfere with debugging. private bool MessageInQueueInternal(IPluginQueue queue, int waitInterval) { try { queue.Peek(TimeSpan.FromSeconds(waitInterval)); return(true); } catch (MessageQueueException mqe) { if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout) { return(false); } if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.AccessDenied) { Logger.Fatal( string.Format( "Do not have permission to access queue [{0}]. Make sure that the current user [{1}] has permission to Send, Receive, and Peek from this queue. NServiceBus will now exit.", Address, WindowsIdentity.GetCurrent().Name)); Thread.Sleep(10000); //long enough for someone to notice System.Diagnostics.Process.GetCurrentProcess().Kill(); } if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.ServiceNotAvailable || mqe.MessageQueueErrorCode == MessageQueueErrorCode.OperationCanceled) { //this exceptions occur after windows restart. This is normal situation. Logger.Warn( "Problem in peeking a message from queue: " + Enum.GetName(typeof(MessageQueueErrorCode), mqe.MessageQueueErrorCode), mqe); Thread.Sleep(100); } else { Logger.Error( "Problem in peeking a message from queue: " + Enum.GetName(typeof(MessageQueueErrorCode), mqe.MessageQueueErrorCode), mqe); } return(false); } catch (ObjectDisposedException) { Logger.Fatal("Queue has been disposed. Cannot continue operation. Please restart this process."); return(false); } catch (Exception e) { Logger.Error("Error in peeking a message from queue.", e); return(false); } }
[DebuggerNonUserCode] // so that exceptions don't interfere with debugging. private Message ReceiveMessageFromQueueAfterPeekWasSuccessful(IPluginQueue queue) { try { //var messageCount = GetNumberOfPendingMessages(); //if (messageCount < MessageCountWhenUiMessagesStopPrioritizing) //{ // try // { // return queue.ReceiveByCorrelationId(HighPriorityMessageCorrelationId); // } // catch (Exception) // { // //pass, receive main message now. // } //} return(queue.Receive(TimeSpan.FromSeconds(SecondsToWaitForMessage), GetTransactionTypeForReceive())); } catch (MessageQueueException mqe) { if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout) { return(null); } Logger.Error( "Problem in receiving message from queue: " + Enum.GetName(typeof(MessageQueueErrorCode), mqe.MessageQueueErrorCode), mqe); return(null); } catch (ObjectDisposedException) { Logger.Fatal("Queue has been disposed. Cannot continue operation. Please restart this process."); return(null); } catch (Exception e) { Logger.Error("Error in receiving message from queue.", e); return(null); } }
/// <summary> /// Starts the transport. /// </summary> public void Start() { if (RoutableTransportMode == RoutableTransportMode.OnDemand) { int workersThreads; int ioThreads; ThreadPool.GetMaxThreads(out workersThreads, out ioThreads); ThreadPool.SetMaxThreads(100 * Environment.ProcessorCount, ioThreads); ThreadPool.SetMinThreads(50, 50); } CheckConfiguration(); CreateQueuesIfNecessary(); if (ErrorQueue != null) { _errorQueue = new MessageQueue(MsmqUtilities.GetFullPath(ErrorQueue)); } if (!string.IsNullOrEmpty(InputQueue)) { IPluginQueue inputQueue = PluginQueueFactory.Create(InputQueue); IPluginQueue commandQueue = PluginQueueFactory.Create(UiCommandInputQueue); if (PurgeOnStartup) { inputQueue.Purge(); commandQueue.Purge(); } Logger.Info(LoggerContext.New(inputQueue.Name), "starting..."); Logger.Info(LoggerContext.New(commandQueue.Name), "starting..."); var factory = new MsmqRouterFactory(Logger, TimeSpan.FromSeconds(SecondsToWaitForMessage), GetTransactionTypeForSend, GetTransactionTypeForReceive()); _inputQueueRouter = CreateAndStartMainMessageConsumer(factory); _uiQueueRouter = CreateAndStartUiMessageConsumer(factory); Logger.Info(LoggerContext.New(inputQueue.Name), "started."); Logger.Info(LoggerContext.New(commandQueue.Name), "started."); _queue = inputQueue; } }
[DebuggerNonUserCode] // so that exceptions don't interfere with debugging. private Message ReceiveMessageFromQueueAfterPeekWasSuccessful(IPluginQueue queue) { try { //var messageCount = GetNumberOfPendingMessages(); //if (messageCount < MessageCountWhenUiMessagesStopPrioritizing) //{ // try // { // return queue.ReceiveByCorrelationId(HighPriorityMessageCorrelationId); // } // catch (Exception) // { // //pass, receive main message now. // } //} return queue.Receive(TimeSpan.FromSeconds(SecondsToWaitForMessage), GetTransactionTypeForReceive()); } catch (MessageQueueException mqe) { if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout) { return null; } Logger.Error( "Problem in receiving message from queue: " + Enum.GetName(typeof(MessageQueueErrorCode), mqe.MessageQueueErrorCode), mqe); return null; } catch (ObjectDisposedException) { Logger.Fatal("Queue has been disposed. Cannot continue operation. Please restart this process."); return null; } catch (Exception e) { Logger.Error("Error in receiving message from queue.", e); return null; } }
[DebuggerNonUserCode] // so that exceptions don't interfere with debugging. private bool MessageInQueueInternal(IPluginQueue queue, int waitInterval) { try { queue.Peek(TimeSpan.FromSeconds(waitInterval)); return true; } catch (MessageQueueException mqe) { if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout) { return false; } if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.AccessDenied) { Logger.Fatal( string.Format( "Do not have permission to access queue [{0}]. Make sure that the current user [{1}] has permission to Send, Receive, and Peek from this queue. NServiceBus will now exit.", Address, WindowsIdentity.GetCurrent().Name)); Thread.Sleep(10000); //long enough for someone to notice System.Diagnostics.Process.GetCurrentProcess().Kill(); } if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.ServiceNotAvailable || mqe.MessageQueueErrorCode == MessageQueueErrorCode.OperationCanceled) { //this exceptions occur after windows restart. This is normal situation. Logger.Warn( "Problem in peeking a message from queue: " + Enum.GetName(typeof(MessageQueueErrorCode), mqe.MessageQueueErrorCode), mqe); Thread.Sleep(100); } else { Logger.Error( "Problem in peeking a message from queue: " + Enum.GetName(typeof(MessageQueueErrorCode), mqe.MessageQueueErrorCode), mqe); } return false; } catch (ObjectDisposedException) { Logger.Fatal("Queue has been disposed. Cannot continue operation. Please restart this process."); return false; } catch (Exception e) { Logger.Error("Error in peeking a message from queue.", e); return false; } }
/// <summary> /// Receives a message from the input queue. /// </summary> /// <remarks> /// If a message is received the <see cref="TransportMessageReceived"/> event will be raised. /// </remarks> private void ReceiveFromQueue(IPluginQueue queue) { var m = ReceiveMessageFromQueueAfterPeekWasSuccessful(queue); if (m == null) { return; } _messageId = m.Id; if (IsTransactional) { if (HandledMaxRetries(m.Id)) { Logger.Error(string.Format("Message has failed the maximum number of times allowed, ID={0}.", m.Id)); MoveToErrorQueue(m, queue); return; } } //exceptions here will cause a rollback - which is what we want. if (StartedMessageProcessing != null) { StartedMessageProcessing(this, null); } var result = Convert(m); var sourceHeader = result.Headers.FirstOrDefault(h => h.Key == TpUnicastBus.SourceQueue); if (sourceHeader == null) { result.Headers.Add(new HeaderInfo { Key = TpUnicastBus.SourceQueue, Value = queue.IndependentAddressForQueue }); } else { sourceHeader.Value = queue.IndependentAddressForQueue; } if (SkipDeserialization) { result.BodyStream = m.BodyStream; } else { try { result.Body = Extract(m); } catch (Exception e) { Logger.Error("Could not extract message data.", e); MoveToErrorQueue(m, queue); OnFinishedMessageProcessing(); // don't care about failures here return; // deserialization failed - no reason to try again, so don't throw } } //care about failures here var exceptionNotThrown = OnTransportMessageReceived(result); //and here var otherExNotThrown = OnFinishedMessageProcessing(); //but need to abort takes precedence - failures aren't counted here, //so messages aren't moved to the error queue. if (_needToAbort) { throw new AbortHandlingCurrentMessageException(); } if (!(exceptionNotThrown && otherExNotThrown)) //cause rollback { throw new ApplicationException("Exception occured while processing message."); } }
private void ReceiveAndProcessMessage(IPluginQueue queue) { _needToAbort = false; _messageId = string.Empty; try { if (IsTransactional) { new TransactionWrapper().RunInTransaction(ReceiveFromQueue, queue, IsolationLevel, TransactionTimeout); } else { ReceiveFromQueue(queue); } ClearFailuresForMessage(_messageId); } catch (AbortHandlingCurrentMessageException) { //in case AbortHandlingCurrentMessage was called return; } catch (Exception e) { Logger.Warn("Failed to process message.", e); if (IsTransactional) { IncrementFailuresForMessage(_messageId); } OnFailedMessageProcessing(); } }
private bool WaitForMessageInQueue(IPluginQueue queue) { return MessageInQueueInternal(queue, SecondsToWaitForMessage); }
private bool MessageInQueue(IPluginQueue queue) { return MessageInQueueInternal(queue, 0); }
private IMessageConsumer<MessageEx> CreateAndStartMessageConsumer(IPluginQueue queue, Func<MessageEx, string> routeBy) { var factory = new MsmqRouterFactory(Logger, TimeSpan.FromSeconds(SecondsToWaitForMessage), GetTransactionTypeForSend, GetTransactionTypeForReceive()); IMessageConsumer<MessageEx> consumer; IMessageSource<MessageEx> messageSource = factory.CreateSource(queue.Name); switch (RoutableTransportMode) { case RoutableTransportMode.OnSite: consumer = factory.CreateConsumer(messageSource); break; case RoutableTransportMode.OnDemand: consumer = factory.CreateRouter(messageSource, factory, routeBy); break; default: throw new ApplicationException(string.Format("{0} plugin hosting mode is not supported", RoutableTransportMode.ToString())); } consumer.IsTransactional = IsTransactional; consumer.IsolationLevel = IsolationLevel; consumer.TransactionTimeout = TransactionTimeout; consumer.Consume(Handle); return consumer; }
/// <summary> /// Receives a message from the input queue. /// </summary> /// <remarks> /// If a message is received the <see cref="TransportMessageReceived"/> event will be raised. /// </remarks> private void ReceiveFromQueue(IPluginQueue queue) { var m = ReceiveMessageFromQueueAfterPeekWasSuccessful(queue); if (m == null) { return; } _messageId = m.Id; if (IsTransactional) { if (HandledMaxRetries(m.Id)) { Logger.Error(string.Format("Message has failed the maximum number of times allowed, ID={0}.", m.Id)); MoveToErrorQueue(m, queue); return; } } //exceptions here will cause a rollback - which is what we want. if (StartedMessageProcessing != null) { StartedMessageProcessing(this, null); } var result = Convert(m); var sourceHeader = result.Headers.FirstOrDefault(h => h.Key == TpUnicastBus.SourceQueue); if (sourceHeader == null) { result.Headers.Add(new HeaderInfo { Key = TpUnicastBus.SourceQueue, Value = queue.IndependentAddressForQueue }); } else { sourceHeader.Value = queue.IndependentAddressForQueue; } if (SkipDeserialization) { result.BodyStream = m.BodyStream; } else { try { result.Body = Extract(m); } catch (Exception e) { Logger.Error("Could not extract message data.", e); MoveToErrorQueue(m, queue); OnFinishedMessageProcessing(); // don't care about failures here return; // deserialization failed - no reason to try again, so don't throw } } //care about failures here var exceptionNotThrown = OnTransportMessageReceived(result); //and here var otherExNotThrown = OnFinishedMessageProcessing(); //but need to abort takes precedence - failures aren't counted here, //so messages aren't moved to the error queue. if (_needToAbort) { throw new AbortHandlingCurrentMessageException(); } if (!(exceptionNotThrown && otherExNotThrown)) //cause rollback { throw new ApplicationException("Exception occured while processing message."); } }
private bool WaitForMessageInQueue(IPluginQueue queue) { return(MessageInQueueInternal(queue, SecondsToWaitForMessage)); }
private bool MessageInQueue(IPluginQueue queue) { return(MessageInQueueInternal(queue, 0)); }
/// <summary> /// Moves the given message to the configured error queue. /// </summary> /// <param name="m"></param> /// <param name="queue"></param> protected void MoveToErrorQueue(Message m, IPluginQueue queue) { m.Label = m.Label + string.Format("<{0}>{1}</{0}><{2}>{3}<{2}>", FAILEDQUEUE, queue.IndependentAddressForQueue, ORIGINALID, m.Id); if (errorQueue != null) { errorQueue.Send(m, MessageQueueTransactionType.Single); } }
/// <summary> /// Starts the transport. /// </summary> public void Start() { CheckConfiguration(); CreateQueuesIfNecessary(); if (ErrorQueue != null) { errorQueue = new MessageQueue(MsmqUtilities.GetFullPath(ErrorQueue)); } if (!string.IsNullOrEmpty(InputQueue)) { _queue = PluginQueueFactory.Create(InputQueue); _uiCommandQueue = PluginQueueFactory.Create(UICommandInputQueue); if (PurgeOnStartup) { _queue.Purge(); _uiCommandQueue.Purge(); } for (var i = 0; i < numberOfWorkerThreads; i++) { AddWorkerThread(Process).Start(); } } }
/// <summary> /// Starts the transport. /// </summary> public void Start() { if (RoutableTransportMode == RoutableTransportMode.OnDemand) { int workersThreads; int ioThreads; ThreadPool.GetMaxThreads(out workersThreads, out ioThreads); ThreadPool.SetMaxThreads(100 * Environment.ProcessorCount, ioThreads); ThreadPool.SetMinThreads(50, 50); } CheckConfiguration(); CreateQueuesIfNecessary(); if (ErrorQueue != null) { _errorQueue = new MessageQueue(MsmqUtilities.GetFullPath(ErrorQueue)); } if (!string.IsNullOrEmpty(InputQueue)) { IPluginQueue inputQueue = PluginQueueFactory.Create(InputQueue); IPluginQueue commandQueue = PluginQueueFactory.Create(UICommandInputQueue); if (PurgeOnStartup) { inputQueue.Purge(); commandQueue.Purge(); } Logger.Info(LoggerContext.New(inputQueue.Name), "starting..."); Logger.Info(LoggerContext.New(commandQueue.Name), "starting..."); _inputQueueRouter = CreateAndStartMessageConsumer(inputQueue, GetQueueNameToRouteMessageIn); _uiQueueRouter = CreateAndStartMessageConsumer(commandQueue, m => TpUnicastBus.GetUiQueueName(GetQueueNameToRouteMessageIn(m))); Logger.Info(LoggerContext.New(inputQueue.Name), "started."); Logger.Info(LoggerContext.New(commandQueue.Name), "started."); _queue = inputQueue; } }