Exemplo n.º 1
0
        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();
            }
        }
Exemplo n.º 2
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);
            }
        }
Exemplo n.º 3
0
        [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);
            }
        }
Exemplo n.º 4
0
        [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;
        }
Exemplo n.º 13
0
        /// <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.");
            }
        }
Exemplo n.º 14
0
 private bool WaitForMessageInQueue(IPluginQueue queue)
 {
     return(MessageInQueueInternal(queue, SecondsToWaitForMessage));
 }
Exemplo n.º 15
0
 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;
            }
        }