public void Ready()
        {
            if (_subscription == null)
            {
                throw new Exception("Subscription not initialized, call Init first");
            }
            if (PriorityQueue == null)
            {
                throw new Exception("PriorityQueue not initialized, call Init first");
            }

            lock (SyncRoot)
            {
                _pool = new SafeSemaphore(_watcher, BatchSize, BatchSize, _sharedSemaphore);
            }

            StartConsumerThread(string.Format("Consumer thread: {0}, Priority queue: {1}", ConsumerTag, _queuePriorirty));
        }
Example #2
0
        /// <summary>
        /// Initialize an object of <see cref="BurrowConsumer"/>
        /// </summary>
        /// <param name="channel">RabbitMQ.Client channel</param>
        /// <param name="messageHandler">An instance of message handler to handle the message from queue</param>
        /// <param name="watcher"></param>
        /// <param name="autoAck">If set to true, the msg will be acked after processed</param>
        /// <param name="batchSize"></param>
        /// <param name="startThread">Whether should start the consuming thread straight away</param>
        protected BurrowConsumer(IModel channel,
                                 IMessageHandler messageHandler,
                                 IRabbitWatcher watcher,
                                 bool autoAck,
                                 int batchSize, bool startThread)
            : base(channel, new SharedQueue<BasicDeliverEventArgs>())
        {
            if (channel == null)
            {
                throw new ArgumentNullException("channel");
            }
            if (messageHandler == null)
            {
                throw new ArgumentNullException("messageHandler");
            }
            if (watcher == null)
            {
                throw new ArgumentNullException("watcher");
            }

            if (batchSize < 1)
            {
                throw new ArgumentException("batchSize must be greater than or equal 1", "batchSize");
            }

            Model.ModelShutdown += WhenChannelShutdown;
            Model.BasicRecoverAsync(true);
            BatchSize = batchSize;

            _pool = new SafeSemaphore(watcher, BatchSize, BatchSize);
            _watcher = watcher;
            _autoAck = autoAck;

            _messageHandler = messageHandler;
            _messageHandler.HandlingComplete += MessageHandlerHandlingComplete;
            _messageHandler.MessageWasNotHandled += MessageWasNotHandled;

            if (startThread)
            {
                StartConsumerThread(string.Format("Consumer thread: {0}", ConsumerTag));
            }
        }
Example #3
0
        public BurrowConsumer(IModel channel,
                              IMessageHandler messageHandler,
                              IRabbitWatcher watcher,

                              bool autoAck,
                              int batchSize)
            : base(channel, new SharedQueue())
        {
            if (channel == null)
            {
                throw new ArgumentNullException("channel");
            }
            if (messageHandler == null)
            {
                throw new ArgumentNullException("messageHandler");
            }
            if (watcher == null)
            {
                throw new ArgumentNullException("watcher");
            }

            if (batchSize < 1)
            {
                throw new ArgumentNullException("batchSize", "batchSize must be greater than or equal 1");
            }

            Model.ModelShutdown += WhenChannelShutdown;
            Model.BasicRecoverAsync(true);
            BatchSize = batchSize;

            _pool = new SafeSemaphore(watcher, BatchSize, BatchSize);
            _watcher = watcher;
            _autoAck = autoAck;


            _messageHandler = messageHandler;
            _messageHandler.HandlingComplete += MessageHandlerHandlingComplete;
            _messageHandler.MessageWasNotHandled += MessageWasNotHandled;
            
            Task.Factory.StartNew(() =>
            {
                try
                {
                    Thread.CurrentThread.Name = string.Format("Consumer thread: {0}", ConsumerTag);
                    while (!_disposed && !_channelShutdown)
                    {
                        WaitAndHandleMessageDelivery();
                    }
                }
                catch (ThreadStateException tse)
                {
                    _watcher.WarnFormat("The consumer thread {0} got a ThreadStateException: {1}, {2}", ConsumerTag, tse.Message, tse.StackTrace);
                }
                catch (ThreadInterruptedException)
                {
                    _watcher.WarnFormat("The consumer thread {0} is interrupted", ConsumerTag);
                }
                catch (ThreadAbortException)
                {
                    _watcher.WarnFormat("The consumer thread {0} is aborted", ConsumerTag);
                }
            }, TaskCreationOptions.LongRunning);
        }
        public void Ready()
        {
            if (_subscription == null)
            {
                throw new Exception("Subscription not initialized, call Init first");
            }
            if (PriorityQueue == null)
            {
                throw new Exception("PriorityQueue not initialized, call Init first");
            }

            lock (SyncRoot)
            {
                _pool = new SafeSemaphore(_watcher, _batchSize, _batchSize, _sharedSemaphore);
            }

            Task.Factory.StartNew(() =>
            {
                try
                {
                    Thread.CurrentThread.Name = string.Format("Consumer thread: {0}, Priority queue: {1}", ConsumerTag, _queuePriorirty);
                    while (!_disposed && !_channelShutdown)
                    {
                        try
                        {
#if DEBUG
                            _watcher.DebugFormat("1. Wait the semaphore to release");
                            _pool.WaitOne();
                            _watcher.DebugFormat("2. Semaphore released, wait a msg from RabbitMQ. Probably a wait-for-ack message is blocking this");
#else
                            _pool.WaitOne();
#endif
                            var msg = PriorityQueue.Dequeue();
                            
                            if (msg != null && msg.Message != null)
                            {
#if DEBUG
                                _watcher.DebugFormat("3. Msg from RabbitMQ arrived (probably the previous msg has been acknownledged), prepare to handle it");

#endif
                                HandleMessageDelivery(msg.Message);
                            }
                            else
                            {
                                _watcher.ErrorFormat("Msg from RabbitMQ arrived but it's NULL for some reason, properly a serious BUG :D, contact author asap, release the semaphore for other messages");
                                _pool.Release();
                            }
                        }
                        catch (EndOfStreamException) // NOTE: Must keep the consumer thread alive
                        {
                            // This happen when the internal Queue is closed. The root reason could be connection problem
                            Thread.Sleep(100);
#if DEBUG                            
                            _watcher.DebugFormat("EndOfStreamException occurs, release the semaphore for another message");

#endif
                            _pool.Release();
                        }
                        catch (BadMessageHandlerException ex)
                        {
                            _watcher.Error(ex);
                            Dispose();
                        }
                    }
                }
                catch (ThreadStateException tse)
                {
                    _watcher.WarnFormat("The consumer thread {0} on queue {1} got a ThreadStateException: {2}, {3}", ConsumerTag, _queuePriorirty, tse.Message, tse.StackTrace);
                }
                catch(ThreadInterruptedException)
                {
                    _watcher.WarnFormat("The consumer thread {0} on queue {1} is interrupted", ConsumerTag, _queuePriorirty);
                }
                catch (ThreadAbortException)
                {
                    _watcher.WarnFormat("The consumer thread {0} on queue {1} is aborted", ConsumerTag, _queuePriorirty);
                }
            }, TaskCreationOptions.LongRunning);
        }