22

Is there any way to count how many time a job is requeued (via Reject or Nak) without manually requeu the job? I need to retry a job for 'n' time and then drop it after 'n' time.

ps : Currently I requeue a job manually (drop old job, create a new job with the exact content and an extra Counter header if the Counter is not there or the value is less than 'n')

fzerorubigd
  • 1,664
  • 2
  • 16
  • 23

2 Answers2

24

Update from 2023 based on quorum queue's way of poison message handling:

Quorum queues keep track of the number of unsuccessful delivery attempts and expose it in the "x-delivery-count" header that is included with any redelivered message.

Original answer (before queue and stream queues were added):

There are redelivered message property that set to true when message redelivered one or more time.

If you want to track redelivery count or left redelivers number (aka hop limit or ttl in IP stack) you have to store that value in message body or headers (literally - consume message, modify it and then publish it modified back to broker).

There are also similar question with answer which may help you: How do I set a number of retry attempts in RabbitMQ?

pinepain
  • 12,453
  • 3
  • 60
  • 65
  • It's worth noting that counting retries on the RabbitMQ side is not implemented and is not so easy to do so, since it would require changing quite a bit of data structures used to store messages. We might implement that in the future, but there's no actually ETA – old_sound Aug 11 '14 at 12:17
  • Exactly, I posted retries counting on application side as a workaround. And it is true that consuming, modifying and then publishing message again has a lot of cons, like stability and performance potential issues, but as a workaround it works. If you will ever think to implement that it would be great (at least it looks like) to have separate plugin for that that utilizes headers modification and respecting, say incrementing `x-redelivered-count` or decrementing `x-redeliveries-left` until it reaches zero and then apllying DLX or AE mechanism or simply drop the message. – pinepain Aug 11 '14 at 13:18
5

In the case that the message was actually dead-lettered, you can check the contents of the x-death message header.

This would for example be the case when you reject/nack with requeue = false and the queue has an associated dead letter exchange.

In that case, the contents of this header is an array. Each element describes a failed delivery attempt, containing information such as the time it was attempted delivered, routing information, etc.

This works for RabbitMQ - I don't know if it is applicable to AMQP in general.

EDIT

Since I originally wrote this answer, the x-death header structure has been changed.

It is generally a very bad thing that headers changes format, but in this particular case the reason was that the message size would grow indefinitely if the message was continuously dead-lettered.

I have therefore removed the piece of code that used to be here to get the no of deaths for a message.

It is still possible to get the number of deaths from the new header format.

Pete
  • 12,206
  • 8
  • 54
  • 70
  • 4
    `x-death` is only added when the message is dead-lettered. – Martin Schröder Feb 18 '16 at 14:14
  • @MartinSchröder - good point - I took the code from an example where we are using dead-letter exchanges to handle redelivery at a later time. I updated the answer to reflect this – Pete Feb 18 '16 at 14:35