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); } }
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."); } }
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); }
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; } }
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); } }
public override void Produce(MessageEx message) { Send(message.Message); _log.Debug(LoggerContext.New(Name), "msg was routed to child queue."); }