public void OnCompleted()
            {
                string name = _producer.Name;

                _producer.Dispose();
                _log.Debug(LoggerContext.New(name), "Killed.");
            }
 private void Handle(MessageEx message)
 {
     _needToAbort = false;
     _messageId   = string.Empty;
     try
     {
         if (IsTransactional)
         {
             new TransactionWrapper().RunInTransaction(() => ReceiveFromQueue(message, ProcessMessage), IsolationLevel, TransactionTimeout);
             ClearFailuresForMessage(_messageId);
         }
         else
         {
             ReceiveFromQueue(message, ProcessMessage);
         }
     }
     catch (AbortHandlingCurrentMessageException)
     {
         //in case AbortHandlingCurrentMessage was called
         return;
     }
     catch (Exception e)
     {
         Logger.Warn(LoggerContext.New(message.MessageOrigin.Name), "Failed to process message.", e);
         if (IsTransactional)
         {
             IncrementFailuresForMessage(_messageId);
         }
         OnFailedMessageProcessing(message);
     }
 }
Ejemplo n.º 3
0
        private Message EndPeekAndReceive(string queueShortName, MessageQueue queue, IAsyncResult asyncResult)
        {
            Message message = queue.EndPeek(asyncResult);

            _log.Info(LoggerContext.New(queueShortName), "End peek msg.");
            return(message);
        }
        private void ProcessMessage(MessageEx message)
        {
            var m = message.Message;

            _messageId = m.Id;
            if (IsTransactional)
            {
                if (HandledMaxRetries(m.Id))
                {
                    Logger.Error(LoggerContext.New(message.MessageOrigin.Name),
                                 string.Format("Message has failed the maximum number of times allowed, ID={0}.", m.Id));
                    MoveToErrorQueue(message);
                    return;
                }
            }
            //exceptions here will cause a rollback - which is what we want.
            if (StartedMessageProcessing != null)
            {
                StartedMessageProcessing(this, null);
            }
            TransportMessage result = Convert(m);

            if (SkipDeserialization)
            {
                result.BodyStream = m.BodyStream;
            }
            else
            {
                try
                {
                    result.Body = Extract(m);
                }
                catch (Exception e)
                {
                    Logger.Error(LoggerContext.New(message.MessageOrigin.Name, result), "Could not extract message data.", e);
                    MoveToErrorQueue(message);
                    OnFinishedMessageProcessing(message);                     // don't care about failures here
                    return;
                }
            }
            //care about failures here
            var exceptionNotThrown = OnTransportMessageReceived(result, message);
            //and here
            var otherExNotThrown = OnFinishedMessageProcessing(message);

            //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.");
            }
        }
Ejemplo n.º 5
0
 public void Dispose()
 {
     if (_subscription != null)
     {
         _subscription.Dispose();
     }
     OnDispose();
     _isRunning = false;
     _log.Info(LoggerContext.New(Name), "disposed.");
 }
        private void ReceiveFromQueue(MessageEx message, Action <MessageEx> processMessageAction)
        {
            var m = message.Message;

            if (m == null)
            {
                Logger.Info(LoggerContext.New(message.MessageOrigin.Name), string.Format("Peek returned null message."));
                return;
            }

            message.DoReceive();
            processMessageAction(message);
        }
Ejemplo n.º 7
0
 public static bool TryDeleteQueue(string queueName, ILoggerContextSensitive log)
 {
     try
     {
         var queue = new PluginQueue(queueName);
         queue.Delete();
         return(true);
     }
     catch (Exception e)
     {
         log.Warn(LoggerContext.New(queueName), "Failed to delete queue {0}. Queue does not exist or no permissions".Fmt(queueName), e);
         return(false);
     }
 }
 private bool OnFailedMessageProcessing(MessageEx message)
 {
     try
     {
         if (FailedMessageProcessing != null)
         {
             FailedMessageProcessing(this, null);
         }
     }
     catch (Exception e)
     {
         Logger.Warn(LoggerContext.New(message.MessageOrigin.Name), "Failed raising 'failed message processing' event.", e);
         return(false);
     }
     return(true);
 }
 private void HandleAsync(MessageEx message)
 {
     _messageId = string.Empty;
     ReceiveFromQueue(message, m => ThreadPool.QueueUserWorkItem(state =>
     {
         try
         {
             ProcessMessage(m);
         }
         catch (Exception e)
         {
             Logger.Warn(LoggerContext.New(message.MessageOrigin.Name), "Failed to process message.", e);
             OnFailedMessageProcessing(message);
         }
     }));
 }
        private bool OnTransportMessageReceived(TransportMessage msg, MessageEx origin)
        {
            try
            {
                if (TransportMessageReceived != null)
                {
                    TransportMessageReceived(this, new TransportMessageReceivedEventArgs(msg));
                }

                Logger.Debug(LoggerContext.New(origin.MessageOrigin.Name, msg), "Transport message received");
            }
            catch (Exception e)
            {
                Logger.Warn(LoggerContext.New(origin.MessageOrigin.Name, msg), "Failed raising 'transport message received' event for message with ID=" + msg.Id, e);
                return(false);
            }
            return(true);
        }
        private void Process(TMessage message)
        {
            _log.Debug(LoggerContext.New(Name), "thread pool info.");
            string messageTag = _tagMessageProvider(message);

            if (string.IsNullOrEmpty(messageTag))
            {
                _handleMessage(message);
                return;
            }

            Receive(message);

            if (!NeedToHandle(message))
            {
                return;
            }

            Preprocess(message);
            Child child = GetOrCreateRouterItem(messageTag);

            child.Producer.Produce(message);
        }
        /// <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;
            }
        }
Ejemplo n.º 13
0
        protected virtual void ConsumeCore(Action <TMessage> handleMessage)
        {
            var @while = While ?? (_ => true);
            Func <IObservable <TMessage> > takeWhile = () => _messageSource.Iterate(handleMessage, _scheduler, s => _log.Info(LoggerContext.New(Name), s)).TakeWhile(m => @while(m));

            _observable   = takeWhile.ToSelfRepairingHotObservable(e => { });
            _subscription = _observable.Subscribe(new CompositeObserver(_observers));
        }
        public IMessageConsumer <MessageEx> CreateConsumer(IMessageSource <MessageEx> messageSource)
        {
            if (!_stopwatch.IsRunning)
            {
                _stopwatch.Start();
            }
            Interlocked.Increment(ref _childrenCount);
            var consumer = new MessageConsumer <MessageEx>(messageSource, Scheduler.ThreadPool, _log);

            consumer.AddObserver(new StopwatchObserver <MessageEx>(_stopwatch, s => _log.Debug(LoggerContext.New(consumer.Name), s), s => _log.Info(LoggerContext.New(consumer.Name), s), e => _log.Error(LoggerContext.New(consumer.Name), string.Empty, e), null, () => Interlocked.Decrement(ref _childrenCount) == 0));
            return(consumer);
        }
        public IMessageConsumer <MessageEx> CreateRouter(IMessageSource <MessageEx> messageSource, IProducerConsumerFactory <MessageEx> factory, Func <MessageEx, string> routeBy)
        {
            var router = new MsmqMessageRouter(messageSource, factory, routeBy, Scheduler.CurrentThread, _log);

            router.AddObserver(new StopwatchObserver <MessageEx>(Stopwatch.StartNew(), s => _log.Debug(LoggerContext.New(router.Name), s), s => _log.Info(LoggerContext.New(router.Name), s), e => _log.Error(LoggerContext.New(router.Name), string.Empty, e)));
            return(router);
        }
        private IEnumerable <IObservable <MessageEx> > GetMessageStream(string sourceName, bool isChild)
        {
            MessageQueue queue         = MessageQueueFactory.GetOrCreateMessageQueue(sourceName);
            var          messageOrigin = new MessageOrigin
            {
                Name = sourceName
            };

            Func <IObservable <Message> > recieveObservableFactory = Observable.FromAsyncPattern(
                (callback, obj) =>
            {
                //Wait infinite time here. Otherwise memory leak occurs.
                return(queue.BeginPeek(TimeSpan.FromMilliseconds(UInt32.MaxValue), obj, callback));
            },
                asyncResult => EndPeekAndReceive(queue, asyncResult));

            while (true)
            {
                var messagesStream = recieveObservableFactory().Select(m => new MessageEx {
                    Message       = m,
                    MessageOrigin = messageOrigin,
                    DoReceive     = () => queue.Receive(TimeSpan.FromSeconds(0), _receiveTransactionType)
                })
                                     .Catch((MessageQueueException e) =>
                {
                    if (e.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                    {
                        _log.Info(LoggerContext.New(sourceName), "Msmq peek timeout occurs");
                        return(Observable.Return <MessageEx>(null));
                    }
                    if (e.MessageQueueErrorCode == MessageQueueErrorCode.AccessDenied)
                    {
                        WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();

                        string accessDeniedMessage = 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.", queue.QueueName, windowsIdentity != null ? windowsIdentity.Name : "no windows identity");
                        _log.Fatal(LoggerContext.New(sourceName), accessDeniedMessage, e);
                        try
                        {
                            EventLog.WriteEntry("TargetProcess Plugin", accessDeniedMessage, EventLogEntryType.Error);
                        }
                        catch (Exception)
                        {
                            //skip exception
                        }

                        //kill the process only if we cannot access main queue (in case of OnDemand it is router queue, in case of OnSite it is main queue)
                        if (!isChild)
                        {
                            _log.Fatal(LoggerContext.New(sourceName), "NServiceBus will now exit.", e);
                            Thread.Sleep(10000);                                                                                                                     //long enough for someone to notice
                            Process.GetCurrentProcess().Kill();
                        }
                    }
                    var message = string.Format("Problem in peeking/receiving a message from queue: {0}", Enum.GetName(typeof(MessageQueueErrorCode), e.MessageQueueErrorCode));
                    if (e.MessageQueueErrorCode == MessageQueueErrorCode.ServiceNotAvailable || e.MessageQueueErrorCode == MessageQueueErrorCode.OperationCanceled)
                    {
                        //this exceptions occur after windows restart. This is normal situation.
                        _log.Fatal(LoggerContext.New(sourceName), message, e);
                    }
                    else
                    {
                        _log.Error(LoggerContext.New(sourceName), message, e);
                    }
                    Thread.Sleep(_waitMessageTimeout);
                    return(Observable.Return <MessageEx>(null));
                })
                                     .Catch((ObjectDisposedException e) =>
                {
                    _log.Fatal(LoggerContext.New(sourceName), "Queue has been disposed. Cannot continue operation. Please restart this process.", e);
                    Thread.Sleep(_waitMessageTimeout);
                    return(Observable.Return <MessageEx>(null));
                })
                                     .Catch((Exception e) =>
                {
                    _log.Error(LoggerContext.New(sourceName), "Error in peeking/receiving a message from queue.", e);
                    Thread.Sleep(_waitMessageTimeout);
                    return(Observable.Return <MessageEx>(null));
                });
                yield return(messagesStream);
            }
        }
Ejemplo n.º 17
0
		public override void Produce(MessageEx message)
		{
			Send(message.Message);
			_log.Debug(LoggerContext.New(Name), "msg was routed to child queue.");
		}