0

I have setup rabbitmq. I want to retry message after 10 second once they fail. But the way I have setup, the message is not getting delayed, it's coming back to queue immediately. I want to wait 10 second before sending message to main_queue.

Below are my code. I am using Bunny Ruby gem.

connection = Bunny.new('url_for_rabbitmq', verify_peer: true)
connection.start
channel = connection.create_channel

# Creating 2 Exchanges (One Main exchange, one retry exchange)

exchange = channel.direct('main_exchange')
retry_exchange = channel.direct('retry_exchange')

# Creating 2 Queue (One Main queue, one retry queue)

queue = channel.queue('main_queue', durable: true, arguments: { 'x-dead-letter-exchange' => retry_exchange.name })
queue.bind(exchange, routing_key: 'foo')
queue.bind(retry_exchange, routing_key: 'foo') # This one is pushing message directly to main queue without waiting for 10 second.

retry_queue = channel.queue('retry_queue', durable: true, arguments: { 'x-message-ttl' => 10_1000, 'x-dead-letter-exchange' => retry_exchange.name })
retry_queue.bind(retry_exchange, routing_key: 'foo')

If i change this line (retry_exchange to exchange)

retry_queue = channel.queue('retry_queue', durable: true, arguments: { 'x-message-ttl' => 10_1000, 'x-dead-letter-exchange' => retry_exchange.name })

to this

retry_queue = channel.queue('retry_queue', durable: true, arguments: { 'x-message-ttl' => 10_1000, 'x-dead-letter-exchange' => exchange.name })

then it works. but the message is coming from main_exchange but I want message to come from retry_exchange. How can i achieve this.

r3b00t
  • 6,953
  • 6
  • 27
  • 37

1 Answers1

0

This is how I solve the problem

connection = Bunny.new('url_for_rabbitmq', verify_peer: true)
connection.start
channel = connection.create_channel

# Creating 2 Exchanges (One Main exchange, one retry exchange)

exchange = channel.direct('main_exchange')
retry_exchange = channel.direct('retry_exchange')

# Creating 2 Queue (One Main queue, one retry queue)

retry_queue = channel.queue('retry_queue', durable: true, arguments: { 'x-message-ttl' => 10_1000, 'x-dead-letter-exchange' => retry_exchange.name })
retry_queue.bind(retry_exchange, routing_key: 'foo')
retry_queue.bind(retry_exchange, routing_key: retry_queue.name)


queue = channel.queue('main_queue', durable: true, arguments: { 'x-dead-letter-exchange' => retry_exchange.name, 'x-dead-letter-routing-key' => retry_queue.name })
queue.bind(exchange, routing_key: 'foo')
queue.bind(exchange, routing_key: retry_queue.name)

basically i needed to add this to main queue 'x-dead-letter-routing-key' => retry_queue.name. and remove couple of unnecessary binding from main queue queue.bind(retry_exchange, routing_key: 'foo')

Now message come to main queue, if it fails then it goes to retry queue. Before going to retry queue, it will remove old routing key foo and replace it with new routing key retry_queue.name. It stays in retry queue for 10 seconds and then again come back to main queue for retry.

r3b00t
  • 6,953
  • 6
  • 27
  • 37