[rabbitmq-discuss] Old consumer tags delivered after re-subscribing to a queue

Juan Wajnerman juan.wajnerman at gmail.com
Fri Apr 2 17:37:11 BST 2010


Matthew, thanks for your reply! Some comments inline:

On Apr 2, 2010, at 1:15 PM, Matthew Sackman wrote:

> On Thu, Apr 01, 2010 at 12:05:25PM -0300, Juan Wajnerman wrote:
>> After unsubscribing from a queue, following "recover" calls will still redeliver unack'd messages through the channel. Even worse, after resubscribing to the queue, the recovered messages are still sent with the old consumer tag.
> 
> The documentation of basic.recover is clear:
> "This method asks the server to redeliver all unacknowledged messages
> on a specified channel."

But what should happen if the subscription was canceled before the messages
were ack'd? The current implementation is still sending the messages with the same consumer tag.

> 
> I don't know the ruby library at all, but I assume from your code below
> they inverted the noAck flag to ack, hence your :ack => true indicates
> you are commiting to acking messages manually. Your code does not do that
> hence every message you receive as part of the subscription is unack'd,
> hence will be redelivered when you issue the recover.

That's right. The omission was completely intentional to reproduce the issue.
I'm sorry, maybe I wasn't clear enough about this. The idea is to cancel the
subscription before the message was ack'd and then resubscribe and perform a recover. 

> 
> Similarly, the documention for basic.cancel (unsubscribe):
> "This method cancels a consumer. This does not affect already delivered
> messages, but it does mean the server will not send any more messages for
> that consumer."

I understand this, but I'm looking at the bits on the wire, and after sending a cancel, the
following recover will send the unack'd messages using the same old consumer tag.

> 
> Thus it is clear that cancelling your subscription does not void your
> commitment to acknowledge the messages you've already been sent.
> 
>> I'm using the amqp ruby library to consume the queues. Here's a small snippet that reproduces the issue. When I execute this, I always get an error similar to: Basic.Deliver for invalid consumer tag: myqueue-396735623077.
> 
> That really shouldn't be happening - and I suspect it's a client bug.
> I've just checked our code - the queue is told to forget about the
> consumer tag on the basic.cancel, and is told about the new consumer
> tag on basic.consume. Your ctag of myqueue-396735623077 is clearly one
> that you, or the library, is specifying - all the server generated
> ctags start "amq.ctag-". I have no idea what the ruby amqp library is
> doing under the bonnet - given that you're not supplying a ctag
> yourself, nor should the library.

I was digging into the source code after sending my email and I found that (correct me if I'm wrong, it's my first time
I look into this code) in rabbit_channel.erl:578 the recover is taking the unack'd messages
and redelivering these using the same ConsumerTag as it was sent before. I think this is
indeed what the FIXME warns: "What should happen if the consumer's been cancelled since?".

> 
> Matthew

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20100402/0b5650a1/attachment.htm 


More information about the rabbitmq-discuss mailing list