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)); }
/// <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)); } }
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); }