IModel closed when trying to BasicAck in EventingBasicConsumer Received handler (.NET C#)

349 views
Skip to first unread message

Hans Isbrücker

unread,
May 4, 2017, 5:40:31 AM5/4/17
to rabbitmq-users
I'm trying to consume a message using the EventingBasicConsumer, however when I try to ack the message the channel (IModel) is already closed. How can I fix this?

channel.BasicQos(0, 1, false); // for fair message dispatch
channel.QueueDeclare(QueueName, true, false, false, null); 

var consumer = new EventingBasicConsumer(channel);

consumer.Received += Consumer_Received;

channel.BasicConsume(QueueName, false, consumer);


And in the Consumer_Received handler (simplified):

protected override void Consumer_Received(object sender, BasicDeliverEventArgs e)
{
    var consumer = sender as EventingBasicConsumer; // confirmed the type by checking the methods firing the Received event    
       var channel = consumer?.Model;

       _eventHandler.Handle(e);

       MessageProcessed(channel, e);

}

protected void MessageProcessed(IModel channel, BasicDeliverEventArgs message)
{
    SendDefaultMessageDone(message); // omitted for brevity
    Ack(channel, message.DeliveryTag);
}

private void Ack(IModel channel, ulong deliveryTag)
{
    Logger.Debug($"Sending Ack for message:{deliveryTag}");
    if (channel == null || channel.IsClosed)
    {
        Logger.Debug($"Channel is null: {channel == null}. Channel closed: {channel?.IsClosed}. Reason: {channel?.CloseReason?.ReplyText ?? "<none>"}");
        Logger.Warn($"Attempting to Ack message {deliveryTag} on channel that is <null> or closed");
        return;
    }

    channel.BasicAck(deliveryTag, false);
}
       

The problem is: the channel I try to ack on is always closed (but not null) with reason "Goodbye".
Using client version 3.5.7 for compatibility reasons.

Karl Nilsson

unread,
May 4, 2017, 6:02:17 AM5/4/17
to rabbitm...@googlegroups.com
Hi,

Are you disposing of the channel after setting up the consumer?

Cheers
Karl 

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Karl Nilsson

Pivotal/RabbitMQ

Hans Isbrücker

unread,
May 4, 2017, 6:52:24 AM5/4/17
to rabbitmq-users
I should have seen it...
So, dispose in handler I presume?

// get a connection
using (var connection = _connectionFactory.CreateConnection())
using (var channel = connection.CreateModel())
{
     try
     {
        channel.BasicQos(0, 1, false); // for fair message dispatch
        channel.QueueDeclare(QueueName, true, false, false, null); 

        var consumer = new EventingBasicConsumer(channel);

        consumer.Received += Consumer_Received;

        channel.BasicConsume(QueueName, false, consumer);
    }
    catch (Exception e)
    {
        Logger.Error(e.Message, e); 
        throw;
    }
}
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-user...@googlegroups.com.
To post to this group, send email to rabbitm...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Karl Nilsson

Pivotal/RabbitMQ

Hans Isbrücker

unread,
May 4, 2017, 7:22:42 AM5/4/17
to rabbitmq-users
Ok, when I updated the code to dispose the channel in the handler (after performing BasicAck and all) the state of the channel is still closed with reason "Connection close forced".

Karl Nilsson

unread,
May 4, 2017, 7:25:09 AM5/4/17
to rabbitm...@googlegroups.com
Connections and channels are meant to be long-lived, typically for the uptime of your applications. You shouldn't dispose of either until you definitely are finished with them.

To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Karl Nilsson

Pivotal/RabbitMQ

Michael Klishin

unread,
May 4, 2017, 8:24:35 AM5/4/17
to rabbitm...@googlegroups.com
It's worth mentioning that channel exceptions (at the protocol level) will close them. Those errors
are considered to be recoverable but it's a responsibility of the app to open new channels.

Connection-level exceptions are very rare and considered to be fatal (e.g. a buggy client or
frames published out of order because a channel was shared between threads for concurrent publishing).

But yes, generally channels and especially connections are long-lived.
MK

Staff Software Engineer, Pivotal/RabbitMQ

Hans Isbrücker

unread,
May 4, 2017, 8:57:58 AM5/4/17
to rabbitmq-users
Check. This explains why after fixing the previous issue (mentioned in this thread) the number of consumers on the queue is exploding while running the application.
Reply all
Reply to author
Forward
0 new messages