- Notifications
You must be signed in to change notification settings - Fork615
Description
Describe the bug
Hi again! I’ve noticed thatAsyncEventingBasicConsumer provides aCancellationToken inBasicDeliverEventArgs during theReceivedAsync event. However, that token never actually gets cancelled. If I close the channel while awaiting inside ReceivedAsync, I’d expect the token to trigger so I can bail out gracefully. Instead, the token stays active, and CloseAsync ends up waiting forever for the task to complete.
Reproduction steps
using RabbitMQ.Client;using RabbitMQ.Client.Events;var factory = new ConnectionFactory{ HostName = "localhost", UserName = "guest", Password = "guest",};const string exchangeName = "TestExchange";const string queueName = "TestQueue";// Setupawait using var connection = await factory.CreateConnectionAsync();var channel = await connection.CreateChannelAsync();await channel.ExchangeDeclareAsync(exchangeName, ExchangeType.Topic);await channel.QueueDeclareAsync(queueName, false, true, true);await channel.QueueBindAsync(queueName, exchangeName, queueName);var consumer = new AsyncEventingBasicConsumer(channel);consumer.ReceivedAsync += async (_, args) =>{ // Wait until cancellation token is cancelled await Task.Delay(-1, args.CancellationToken);};await channel.BasicConsumeAsync(queueName, true, consumer);// Publishawait channel.BasicPublishAsync(exchangeName, queueName, "Hello"u8.ToArray());// Give some time for the message to be processedawait Task.Delay(100);// Closeawait channel.CloseAsync();await connection.CloseAsync();Console.WriteLine("All good!");Expected behavior
TheCancellationToken provided inBasicDeliverEventArgs is cancelled when the channel closes (or is aborted), allowing the awaiting task to end quickly.
Additional context
I poked around in the code and noticed a token is never actually passed toIAsyncBasicConsumer.HandleBasicDeliverAsync.
I tried creating aCancellationTokenSource in theChannel class that I cancel inCloseAsync, then using its token when callingHandleBasicDeliverAsync. That change made things work as expected.
If you want, I can make pull request containing this fix.