Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Channel.waitForConfirmsOrDie block?

Tags:

rabbitmq

I have a publish-subscribe use case where I would like to block on the publish side until each of the subscribers confirm that they have completed handling the message sent by the publisher.

I (incorrectly?) assumed that I could use RabbitMQ and its Java amqp-client's Channel.waitForConfirmsOrDie method as part of my solution. The issue is that I haven't found a case in which waitForConfirmsOrDie will actually block.

According to the javadocs, waitForConfirmsOrDie is supposed to:

Wait until all messages published since the last call have been either ack'd or nack'd by the broker. If any of the messages were nack'd, waitForConfirmsOrDie will throw an IOException. When called on a non-Confirm channel, it will return immediately.

In order to test that this method really works, I started with this example code from the RabbitMQ website.

The example code creates a publisher and a consumer, each on its own separate thread. Then the publisher sends messages to the exchange while the consumer consumes the messages. It seems that the publisher is supposed to block until all of the messages are ack'd via its call to waitForConfirmsOrDie().

This example code seemed like it matched up perfectly with what I was trying to do. But, it doesn't seem to work the way I thought it did. In fact, if, in the consumer thread, I turn off auto-acking messages, then waitForConfirmsOrDie() still returns immediately.

I turned off auto ack by just changing one false to true: ch.queueDeclare(QUEUE_NAME, false, false, false, null); becomes ch.queueDeclare(QUEUE_NAME, true, false, false, null); (2nd arg false instead of true). I believe this means that acks should no longer be sent by the consumer.

So what does waitForConfirmsOrDie() actually do? When would it block?

If waitForConfirmsOrDie doesn't do what I want, is there a way to make a publisher wait until all subscribers ack a message before proceeding?

like image 896
xnickmx Avatar asked Oct 30 '12 04:10

xnickmx


1 Answers

As far as I understand those calls are not supposed to wait for confirmation from consumer. The purpose of waitForConfirms* methods is making sure your message was delivered to broker and to provide basic delivered/failed type of notification. In other words, message will not disappear without notifying produces in case if one of rmq nodes (or even all of nodes) failed/unavailable.

You can see this exception in action if you disconnect or turn off rmq before basicPublish call.

like image 159
Umputun Avatar answered Oct 15 '22 20:10

Umputun