0

Working on a C# project that uses Rabbit. I've found what appears to me as conflicting information in the documentation regarding when a message is redelivered as a result of either a connection or channel dying (which one is it?)

The docs here: http://www.rabbitmq.com/semantics.html

State that it is requeued for delivery when a channel closes

Messages can be returned to the queue using AMQP methods that feature a requeue parameter (basic.recover, basic.reject and basic.nack), or due to a channel closing while holding unacknowledged messages. Any of these scenarios caused messages to be requeued at the back of the queue for RabbitMQ releases earlier than 2.7.0. From RabbitMQ release 2.7.0, messages are always held in the queue in publication order, even in the presence of requeueing or channel closure.

But here: http://www.rabbitmq.com/tutorials/tutorial-two-dotnet.html

States: Only when the worker connection dies

If a consumer dies without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will redeliver it to another consumer. That way you can be sure that no message is lost, even if the workers occasionally die.

There aren't any message timeouts; RabbitMQ will redeliver the message only when the worker connection dies. It's fine even if processing a message takes a very, very long time.

So when does redelivery actually happen? When the worker or the channel dies? Can I Consume on one channel but ACK on another channel?

Currently I created a ChannelManager class that opens N channels and stores them in a ConcurrentQueue and Queues / Dequeues Channels as they are needed, and also ensures we never fall below the 'minimum' available channel count. With this method there is no way for me to ensure the Consume and Ack happen on the same channel...

Wesley Lomax
  • 2,067
  • 2
  • 20
  • 34
Wjdavis5
  • 3,952
  • 7
  • 35
  • 63

2 Answers2

4

The second quote is worded incorrectly, though the context around that worker page is still correct... that sentence you put in bold would correctly changed to:

RabbitMQ will redeliver the message when the consumer dies.

saying it this way will not exclude the other legitimate cases, but would illustrate they point they are making in this article.

...

If you want messages to be re-queued and re-delivered, you must ensure the noAck setting is false (this is the default). Once you have that, the first paragraph you quoted is correct.

...

regarding your ChannelManager - unnecessary. channels are cheap, quick things that can be stood up and torn down as needed. it's ok to have only 1 open channel or to have 1,000 open channels as long as you are using all of the open channels.

connections, on the other hand, are expensive. open a single connection for each app instance. then use as many channels as you need, within that connection.

Derick Bailey
  • 72,004
  • 22
  • 206
  • 219
0

First, a having a "channel pool" as I'll call it adds harmful complication to your application. Channels are absolutely not to be shared among threads. Think of a channel as an endpoint identifier - it doesn't represent a separate connection to the broker, but rather a distinct discussion with the broker over a connection - read more here.

Second, a tutorial is not really documentation. It can be helpful in understanding how the broker works, but I would ordinarily expect things written as part of a tutorial to be specific to the scenario depicted in that tutorial. In this case, the documentation explains the situations when messages might be requeued.

Third, requeue and redelivery are separate things. A redelivery can only happen after a requeue, but is not guaranteed. For example, a message may expire after it is requeued, but before it is redelivered (possibly because there were no consumers available to take the message, or it waited too long in the queue).

Finally, every message delivered to a consumer is issued a delivery tag. That tag is specific to the channel AND the consumer on the channel. So, it is not possible to ack from another channel, because the other channel lacks the contextual awareness of the delivery tag.

theMayer
  • 15,456
  • 7
  • 58
  • 90