Exemplo n.º 1
0
        internal virtual void WaitAndHandleMessageDelivery()
        {
            try
            {
                BasicDeliverEventArgs deliverEventArgs = null;
                lock (_sharedQueueLock)
                {
#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
                    if (!_disposed)
                    {
                        deliverEventArgs = Queue.Dequeue();
                    }
#if DEBUG
                    _watcher.DebugFormat("3. Msg from RabbitMQ arrived (probably the previous msg has been acknownledged), prepare to handle it");
#endif
                }
                if (deliverEventArgs != null)
                {
                    HandleMessageDelivery(deliverEventArgs);
                }
                else
                {
                    _watcher.ErrorFormat("Message arrived but it's null for some reason, properly a serious BUG :D, contact author asap, release semaphore for other messages");
                    _pool.Release();
                }
            }
            catch (EndOfStreamException)
            {
                // This thread will be ended soon because the new consumer will be created
                // do nothing here, EOS fired when queue is closed
                // Looks like the connection has gone away, so wait a little while
                // before continuing to poll the queue
                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();
            }
        }
Exemplo n.º 2
0
        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);
        }