<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Matthew, thanks for your reply! Some comments inline:</div><div><br><div><div>On Apr 2, 2010, at 1:15 PM, Matthew Sackman wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>On Thu, Apr 01, 2010 at 12:05:25PM -0300, Juan Wajnerman wrote:<br><blockquote type="cite">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.<br></blockquote><br>The documentation of basic.recover is clear:<br>"This method asks the server to redeliver all unacknowledged messages<br>on a specified channel."<br></div></blockquote><div><br></div><div>But what should happen if the subscription was canceled before the messages</div><div>were ack'd? The current implementation is still sending the messages with the same consumer tag.</div><br><blockquote type="cite"><div><br>I don't know the ruby library at all, but I assume from your code below<br>they inverted the noAck flag to ack, hence your :ack => true indicates<br>you are commiting to acking messages manually. Your code does not do that<br>hence every message you receive as part of the subscription is unack'd,<br>hence will be redelivered when you issue the recover.<br></div></blockquote><div><br></div><div>That's right. The omission was completely intentional to reproduce the issue.</div><div>I'm sorry, maybe I wasn't clear enough about this. The idea is to cancel the</div><div>subscription before the message was ack'd and then resubscribe and perform a recover. </div><br><blockquote type="cite"><div><br>Similarly, the documention for basic.cancel (unsubscribe):<br>"This method cancels a consumer. This does not affect already delivered<br>messages, but it does mean the server will not send any more messages for<br>that consumer."<br></div></blockquote><div><br></div><div>I understand this, but I'm looking at the bits on the wire, and after sending a cancel, the</div><div>following recover will send the unack'd messages using the same old consumer tag.</div><br><blockquote type="cite"><div><br>Thus it is clear that cancelling your subscription does not void your<br>commitment to acknowledge the messages you've already been sent.<br><br><blockquote type="cite">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.<br></blockquote><br>That really shouldn't be happening - and I suspect it's a client bug.<br>I've just checked our code - the queue is told to forget about the<br>consumer tag on the basic.cancel, and is told about the new consumer<br>tag on basic.consume. Your ctag of myqueue-396735623077 is clearly one<br>that you, or the library, is specifying - all the server generated<br>ctags start "amq.ctag-". I have no idea what the ruby amqp library is<br>doing under the bonnet - given that you're not supplying a ctag<br>yourself, nor should the library.<br></div></blockquote><div><br></div><div>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</div><div>I look into this code) in rabbit_channel.erl:578 the recover is taking the unack'd messages</div><div>and redelivering these using the same ConsumerTag as it was sent before. I think this is</div><div>indeed what the FIXME warns: "What should happen if the consumer's been cancelled since?".</div><div><br></div><blockquote type="cite"><div><font class="Apple-style-span" color="#000000"><br></font>Matthew<br></div></blockquote></div><br></div></body></html>