[rabbitmq-discuss] Message deleted at subscription?

Matthias Radestock matthias at lshift.net
Sun Jan 18 09:41:02 GMT 2009


Julien,

Julien Genestoux wrote:
> A process puts messages in a queue every second roughly. Atfer some 
> time, I check the queue.
>  > rabbitmqctl list_queues messages name consumers
> Listing queues ...
> 508    /queue/MyQueue    0
> 
> Now, I start a consumer with the following code :
> 
> queue_client.subscribe("/queue/FeedsToParse", {:durable => true, 
> "auto-delete".intern => false}) do |message|
>   sleep 600
>   puts "done!"
> end
> 
> As you can see, when starting this client, the number of elements in my 
> queue should decrease pretty slowly (1 every 10 minutes)... but here is 
> what happens if I check the queue again:
>  > rabbitmqctl list_queues messages name consumers
> Listing queues ...
> 417    /queue/MyQueue    1
> 
> So it seems that starting a consumer deletes some messages in the queue. 
> I have no idea why. Can anyone explain?

The 'messages' count is the sum of:

- messages_ready - Number of ready messages (i.e. messages ready to be 
delivered to client)

- messages_unacknowledged - Number of unacknowledged messages.

- messages_uncommitted - Number of uncommitted messages (i.e. messages 
published in a transaction but not yet committed)

Since your example does not involve transactions, only messages_ready + 
messages_unacknowledged come into play.

On publication, messages_ready increases.

When delivering messages to a client, messages_ready decreases and 
messages_unacknowledged increases by the same amount, so the sum remains 
the same.

When an acknowledgement is received from the client, 
messages_unacknowledged decreases, and so does the sum.

Now ...

I am familiar with Aman's ruby client, but looking at the code and docs 
it appears that by default the subscribe method creates a consumer from 
which the server does not expect acknowledgements (and indeed there is 
no explicit ack in the code above). Here's what ruby client's docs say;

     # == Options
     # * :ack => true | false (default false)
     # If this field is set to false the server does not expect 
acknowledgments
     # for messages. That is, when a message is delivered to the client
     # the server automatically and silently acknowledges it on behalf
     # of the client. This functionality increases performance but at
     # the cost of reliability. Messages can get lost if a client dies
     # before it can deliver them to the application.

So as soon as your code creates the subscription, the server will start 
sending it the queue's messages (resulting in messages_ready to 
decrease) and automatically acknowledge all such messages (resulting in 
messages_unacknowledged to remain unchanged), and thus the 'messages' 
count decreases. This is an asynchronous operation; so the client will 
receive a stream of messages without having to do anything. The stream 
is only paused by network/tcp congestion, and basic.qos (search the 
archives for discussions on the latter).

If that is not what you want I suggest you change the flag to true and 
explicitly acknowledge messages in your code.


Regards,

Matthias




More information about the rabbitmq-discuss mailing list