8000 Event handlers for Channel.ChannelShutdownAsync and Consumer.ShutdownAsync are all called on the last registration? · Issue #1837 · rabbitmq/rabbitmq-dotnet-client · GitHub
[go: up one dir, main page]

Skip to content

Event handlers for Channel.ChannelShutdownAsync and Consumer.ShutdownAsync are all called on the last registration? #1837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
viblo-majority opened this issue May 21, 2025 · 3 comments
Labels

Comments

@viblo-majority
Copy link
viblo-majority commented May 21, 2025

Describe the bug

If I create two channels with a consumer each, register a ChannelShutdownAsync callback and then break the connection I will get two callbacks, but both of them will go to the last callback registered.

Im not sure if this is a bug or if it is intendend.. but at least I think it is a bit confusing.

In my example below I get this output:

Queue Receive Test
Consumer 0 started on queue-0
Consumer 1 started on queue-1
Setup complete. Waiting...
Connection shutdown
Channel 2 shutdown: 1 queue-0 False
Consumer 2 shutdown: queue-0 True
Channel 2 shutdown: 2 queue-1 False
Consumer 2 shutdown: queue-1 True

I thought that each callback registered would be called once, and not the same callback twice:

...
Channel 1 shutdown: 1 queue-0 False
Consumer 1 shutdown: queue-0 True
Channel 2 shutdown: 2 queue-1 False
Consumer 2 shutdown: queue-1 True

Reproduction steps

Run the below code (with adjusted rabbit connection details), and when its running then break the connection to rabbit, for example by turning it off if run locally.

using RabbitMQ.Client;
using RabbitMQ.Client.Events;

Console.WriteLine("Queue Receive Test");

var connectionFactor = new ConnectionFactory
{
    HostName = "localhost",
    Port = 5672,
    VirtualHost = "/",
    UserName = "user",
    Password = "password"
};

var connection = await connectionFactor.CreateConnectionAsync();

connection.ConnectionShutdownAsync += (sender, e) =>
{
    Console.WriteLine($"Connection shutdown");
    return Task.CompletedTask;
};

for (int i = 0; i < 2; i++)
{
    var channel = await connection.CreateChannelAsync();

    channel.ChannelShutdownAsync += (sender, e) =>
    {
        var c = (IChannel)sender;
        Console.WriteLine($"Channel {i} shutdown: {c.ChannelNumber} {c.CurrentQueue} {c == channel}");
        return Task.CompletedTask;
    };
    var queueName = $"queue-{i}";
    await channel.QueueDeclareAsync(queueName, true, false, false);

    var consumer = new AsyncEventingBasicConsumer(channel);
    consumer.ShutdownAsync += (sender, e) =>
    {
        var c = (AsyncEventingBasicConsumer)sender;
        Console.WriteLine($"Consumer {i} shutdown: {c.Channel.CurrentQueue} {c==consumer}");
        return Task.CompletedTask;
    };
    consumer.ReceivedAsync += async (model, ea) =>
    {
        Console.WriteLine($"Received from {queueName}");
        await channel.BasicAckAsync(ea.DeliveryTag, false);
    };
    await channel.BasicConsumeAsync(queueName, false, consumer);
    Console.WriteLine($"Consumer {i} started on {queueName}");
}
await connection.CloseAsync();

Console.WriteLine("Setup complete. Waiting...");
Console.ReadLine();

Expected behavior

I expected a call to each callback I register, not double callbacks to the last callback registered.

Additional context

No response

@Gsantomaggio
Copy link
Member
Gsantomaggio commented May 28, 2025

@viblo-majority,I am not sure I understand the problem.

Your code is wrong btw, you are using the variable i out of scope. Please try the following:

using RabbitMQ.Client;
using RabbitMQ.Client.Events;

Console.WriteLine("Queue Receive Test");

var connectionFactor = new ConnectionFactory
{
    HostName = "localhost",
    Port = 5672,
    VirtualHost = "/",
};

var connection = await connectionFactor.CreateConnectionAsync();

connection.ConnectionShutdownAsync += (sender, e) =>
{
    Console.WriteLine($"Connection shutdown");
    return Task.CompletedTask;
};

int count = 0;
for (var i = 0; i < 2; i++)
{
    var channel = await connection.CreateChannelAsync();
    // Console.WriteLine($"Channel {i} created: {channel.ChannelNumber} {channel.CurrentQueue} {channel}");

    channel.ChannelShutdownAsync += (sender, e) =>
    {
        var c = (IChannel)sender;
        Console.WriteLine(
            $"[ChannelShutdownAsync] Channel {c.ChannelNumber} shutdown: {c.ChannelNumber} {c.CurrentQueue} {c.ChannelNumber == channel.ChannelNumber}");
        return Task.CompletedTask;
    };
    var queueName = $"queue-{i}";
    await channel.QueueDeclareAsync(queueName, true, false, false);

    var consumer = new AsyncEventingBasicConsumer(channel);
    consumer.ShutdownAsync += (sender, e) =>
    {
        var c = (AsyncEventingBasicConsumer)sender;
        Console.WriteLine(
            $"[ShutdownAsync] Consumer {c.Channel.ChannelNumber} shutdown: {c.Channel.CurrentQueue} {c == consumer}");
        return Task.CompletedTask;
    };
    consumer.ReceivedAsync += async (model, ea) =>
    {
        Console.WriteLine($"Received from {queueName}");
        await channel.BasicAckAsync(ea.DeliveryTag, false);
    };
    await channel.BasicConsumeAsync(queueName, false, consumer);
    Console.WriteLine($"Consumer with channel id:{channel.ChannelNumber} started on {queueName}");
}

// Thread.Sleep(500);
await connection.CloseAsync();

Console.WriteLine("Setup complete. Waiting...");
Console.ReadLine();

result:

Queue Receive Test
Consumer with channel id:1 started on queue-0
Consumer with channel id:2 started on queue-1
Connection shutdown
[ChannelShutdownAsync] Channel 1 shutdown: 1 queue-0 True
[ShutdownAsync] Consumer 1 shutdown: queue-0 True
[ChannelShutdownAsync] Channel 2 shutdown: 2 queue-1 True
[ShutdownAsync] Consumer 2 shutdown: queue-1 True

@Gsantomaggio
Copy link
Member

I think we can close this. cc @lukebakken @michaelklishin

@Gsantomaggio
Copy link
Member

@viblo-majority I am going to close the issue. Feel free to reopen in case of problems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants
0