protected MsmqMessageProducerBase(string queueName, Func <MessageQueueTransactionType> transactionType) { _name = queueName + "~producer"; _queue = MessageQueueFactory.GetOrCreateMessageQueue(queueName); _transactionType = transactionType; }
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); } }