Skip to content

Improve behavior of topology recovery when channels have been closed #487

Closed
@teemumurtola

Description

@teemumurtola

Consider the following code fragment using the RabbitMQ.Client library:

var connection = ...; // create connection with connection recovery and topology recovery on
using (var channel = connection.CreateModel())
{
channel.QueueDeclare("MyQueue", exclusive: true);
channel.Close();
}
... // Create a separate channel and start a consumer on "MyQueue"

After this has executed, assume that the connection to RabbitMQ breaks and is recovered. What should happen?

At least in RabbitMQ.Client (tested on version 5.0.1, but the recovery code still looks about the same in current master), "MyQueue" is not created on recovery, but rather multiple exceptions get thrown. The first one is an "AlreadyClosed" exception, from trying to declare "MyQueue", followed by exceptions from the consumer not finding the queue.

The behavior is not intuitive. I would expect that either

  1. MyQueue is created on reconnection, or
  2. Recreation of MyQueue is not even attempted, avoiding the exceptions.

The reason for this seems to be that the AutorecoveringModel that is used to call QueueDeclare() is recorded in RecordedQueue, and then the topology recovery calls QueueDeclare() on it. But since that channel has already been disposed, this fails. Possible solutions could be to either

  1. The recovery should work on channels that may not be the original ones (there can be some complications here; haven't thought about it that much),
  2. Closed channels should get reopened for recovery and then closed again, or
  3. Recorded entities for closed channels should get thrown away.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions