[rabbitmq-discuss] Java waitForConfirmsOrDie(timeout) can block indefinitely

Michael Klishin mklishin at gopivotal.com
Thu Oct 24 17:33:07 BST 2013


On 24 Oct 2013, at 18:40, Stuart Sierra <stuart.sierra at cognitect.com> wrote:

> Is this intentional?
> 
> I tested this with RabbitMQ 3.2.0 and the official Java client 3.2.0.
> 
> Steps to reproduce:
> 	• Start a RabbitMQ broker
> 	• Connect with the Java client
> 	• Create a Channel and call `confirmSelect`
> 	• Run `rabbitmqctl set_vm_memory_high_watermark 0.0`
> 	• Call `basicPublish` to publish a message
> 	• Call `Channel.waitForConfirmsOrDie(1000L)`
> 	• Wait for more than 1 second: no exception
> 	• Run `rabbitmqctl set_vm_memory_high_watermark 0.4`
> 	• TimeoutException is thrown
> I think this is because ChannelN.waitForConfirmsOrDie(long timeout) catches TimeoutException and calls:
> 
> close(AMQP.PRECONDITION_FAILED, "TIMEOUT WAITING FOR ACK");
> 
> The call to `close` blocks indefinitely because the RabbitMQ connection is blocked. The TimeoutException does not get thrown until after the connection is unblocked.

This is not intentional, just an edge case that isn’t covered well.

With 3.2, clients will get notifications when their connections are blocked, so we can use this information
to throw an exception before calling #close(). Unfortunately, it is much trickier with older
RabbitMQ versions.

MK


More information about the rabbitmq-discuss mailing list