question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

What is the best way to clean up durable queues created by EasyNetQ?

See original GitHub issue

Hi,

I’m trying to figure out how to correctly clean up durable queues which are created inside of SubscribeAsync method in RabbitBus class. We have the following restrictions

  1. We need to have durable queues because we don’t want to miss messages due to the fact that we have no consumers at the moment or we have some troubles with our message broker (this can happen mostly due to technical reasons - consumer services have suddenly stopped or smth else). As I can see EasyNetQ uses durable queues by default, so it should work out of the box.
  2. We need to clean up ‘dead’ queues which are guaranteed to have no subscribers (due to changes in application code or for some other reasons). We don’t want to keep these ‘dead’ queues to ensure that they won’t consume server resources since we already don’t need them (they accumulate messages that will never be processed).

We considered following options to address our concerns

  1. Use ‘Autodelete’ on subscription. We can’t use autodelete because of restriction 1 - we have a possibility to have no consumers due to technical reasons and issues but we still want to be able to process messages from the queue in the future when all issues will be fixed.
  2. Use ‘Expires’ setting on subscription. This option can work for us but requires additional operational overhead to monitor such ‘dead’ queues and understand why they accumulate messages - because it’s unused and should be removed or because something has happened and we need to restart our consumer services.
  3. Try to delete queue with ifUnused = true and ifEmpty = true flags when ISubscriptionResult is disposed. This option seems to be the most convenient for us because we will remove queue only when an application has clear intention to stop message consumption from a queue, not due to technical reasons. We have tried to implement this option but faced with following issues
    1. We tried to call AdvancedBus.QueueDelete method right after calling ISubscriptionResult.Dispose. This isn’t working because actual disposal of consumer executes on separate thread inside of consumerDispatcher (see https://github.com/EasyNetQ/EasyNetQ/blob/2.3.1/Source/EasyNetQ/Consumer/InternalConsumer.cs#L316) and when we call AdvancedBus.QueueDelete there is no guarantee that consumer has been actually disposed and the queue can be considered as in use (we have a race condition here due to asynchronous Dispose execution).
    2. Subscribe on ConsumerModelDisposedEvent via IEventBus instance. This option seems to be working since this event is published when a consumer has been actually disposed, but all information that we have inside of handler of ConsumerModelDisposedEvent is ConsumerTag which can not be accessed or configured from outside world and it seems to be a part of an internal stuff of EasyNetQ. And due to this fact, we can’t figure out what exactly queue we should try to remove inside of handler of this event.

So, my questions are:

  1. Is it possible to implement option 3 - delete queue when a consumer is disposed? I see 2 possible options here
    1. Make ISubscriptionResult.Dispose synchronous which means that consumer is guaranteed to be disposed when this method will be finished.
    2. Add access to ConsumerTag to use this information on handling of ConsumerModelDisposedEvent. Here is we have yet another 2 options 😃
      1. Allow to configure ConsumerTag in ISubscriptionConfiguration and use it when declaring consumers
      2. Return ConsumerTag inside of ISubscriptionResult
  2. Maybe there are some alternative ways to clean up durable queues that are guaranteed to have no subscribers?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:9
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
kkovalevskiycommented, May 15, 2018

Sorry for a delayed response, we decided to follow with option #2, but with separate monitoring of consumer applications to be sure that if a queue has no consumer, it’s actually unused not because of a sudden death of consumers but because it’s actually unused and can be removed. Thank you for your help!

0reactions
zidadcommented, May 15, 2018

No worries, thanks for the feedback!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Set durable / transient Queue in EasyNetQ
Hello everybody, ist it possible to specify the type of queue (durable / transient) via RabbitHutch ? If yes, where can I find...
Read more >
EasyNetQ Exclusive queue disposing - rabbitmq
I'm using EasyNetQ / Rabbitmq i'm creating 10 exclusives queues, that's wait for a message, unfortunatly all theses queues are disposed ...
Read more >
EasyNetQ: Consumer Cancellation
If the queue is deleted, EasyNetQ simply stops consuming from it. Attempting to re-create it is probably wrong because we assume that the...
Read more >
RabbitMQ: AMQP Channel Best Practices - Code rant
The main implementation issue is that we need to clean up any replies queues in the event that a problem with the server...
Read more >
Part 1: RabbitMQ Best Practices
If you cannot afford to lose any messages, make sure that your queue is declared as “durable” and that messages are sent with...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found