[rabbitmq-discuss] How to shutdown cleanly a Java application using Consumers?

Simon MacMullen simon at rabbitmq.com
Thu Apr 3 17:47:15 BST 2014

On 03/04/14 17:28, Bertrand Guay-Paquet wrote:
> I tested this on RabbitMQ 3.2.4 and calling basicCancel for a consumer
> tag does not interfere with the ability to basicAck a message currently
> being processed

That is correct.

> (I used Thread.sleep() in the consumer to ensure the
> operation order). The handleCancelOk() method is only called after the
> handleDelivery() method returns.

That is also correct.

>  From what I could piece together, calling basicCancel queues the
> channel rpc command for execution after whatever is already queued. The
> consumer even consumes its buffered messages (basicQos > 1) before
> processing the cancel command.

So there has been a certain lack of clarity in this thread. Two key points:

* It is absolutely fine and normal to acknowledge a message after its 
consumer has been cancelled. The message remains acknowledgeable until 
the channel it was delivered on closes.

* Once you have received basic.cancel-ok, you will not receive any more 
deliveries for that consumer.

So the way to cleanly[0] shut down a consumer in the Java client is:

1) Invoke basicCancel()
2) Process and acknowledge messages as usual
3) When handleCancelOk() gets called and you have acknowledged all 
messages you received before it, you can then consider yourself done, 
close channels and connections as appropriate.

[0] I am assuming "cleanly" here means without causing messages to be 
redelivered. Otherwise you can just pull the network cable :-)

Cheers, Simon

Simon MacMullen
RabbitMQ, Pivotal

More information about the rabbitmq-discuss mailing list