/// <summary>
 /// Acknowledge the message arrival and processing, so that RabbitMq can remove it from the queue.
 /// </summary>
 /// <param name="msg">The message instance</param>
 public void Ack(RabbitWorkMessage msg)
 {
     if (ConsumerChannel.IsOpen)
     {
         ConsumerChannel.BasicAck(msg.DeliveryTag, false);
     }
 }
        private bool CheckRetryLimit(long retryLimit, RabbitWorkMessage msg)
        {
            IBasicProperties properties = msg.BasicProperties;

            if (retryLimit <= 0)
            {
                return(true);
            }

            // check dead-letter counter (number of times the message was dlx)
            long count = msg.GetRetryCount();

            // check dlx count against our threshold
            if (count >= retryLimit)
            {
                // move message to dead-letter queue
                if (String.IsNullOrEmpty(deadLetterQueue))
                {
                    // create dead letter queue
                    lock (QueueName)
                    {
                        deadLetterQueue = QueueName + ".dead-letter";
                        deadLetterQueue = EnsureQueueExists(deadLetterQueue, Mode);
                    }
                }
                // publish message to the deadletter queue
                PublishChannel.BasicPublish("", deadLetterQueue, (IBasicProperties)properties.Clone(), msg.Body);
                // delete message
                Ack(msg);
                return(false);
            }
            return(true);
        }
        /// <summary>
        /// Get messages from the queue.
        /// </summary>
        /// <param name="millisecondsTimeout">The wait timeout in milliseconds for a message to arrive. -1 for infinite timeout</param>
        /// <param name="noAck">If the acknowledgement will be manual (noAck == false) or automatic (true).</param>
        public IEnumerable <RabbitWorkMessage> Get(int millisecondsTimeout, bool noAck = false)
        {
            RabbitMQ.Client.Events.BasicDeliverEventArgs item;
            bool done = false;

            while (!done)
            {
                done = true;
                using (var sub = new RabbitMQ.Client.MessagePatterns.Subscription(ConsumerChannel, QueueName, noAck))
                {
                    while (sub.Next(millisecondsTimeout, out item))
                    {
                        if (item == null)
                        {
                            // in case of a connection close, the item will be null and we should re-subscribe
                            done = false;
                            break;
                        }

                        // if the message is within the retry threshold, proceed...
                        var msg = new RabbitWorkMessage(this, item);
                        if (CheckRetryLimit(_maxRetry, msg))
                        {
                            yield return(msg);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Negative acknowledge the message, the message will be returned to the queue or send to dead letter exchange.
 /// </summary>
 /// <param name="msg">The message instance</param>
 /// <param name="requeue">False will send to dead letter exchange, true will send back to the queue.</param>
 private void Nack(RabbitWorkMessage msg, bool requeue = false)
 {
     if (ConsumerChannel.IsOpen)
     {
         // check max retry limit
         if (!requeue && !CheckRetryLimit(_maxRetry - 1, msg))
         {
             return;
         }
         ConsumerChannel.BasicNack(msg.DeliveryTag, false, requeue);
     }
 }
 /// <summary>
 /// Rejects the message and returns it to the queue. This does not count against the maxRetry counter.
 /// </summary>
 /// <param name="msg">The message instance</param>
 public void Requeue(RabbitWorkMessage msg)
 {
     Nack(msg, true);
 }
 /// <summary>
 /// Negative acknowledge the message, the message will be marked as a try and send to dead letter exchange according to the maxRetry threshold.
 /// </summary>
 /// <param name="msg">The message instance</param>
 public void Nack(RabbitWorkMessage msg)
 {
     Nack(msg, false);
 }