-
Notifications
You must be signed in to change notification settings - Fork 598
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
Queue Fails to Delete with Orphaned Binding #1376
Comments
I went through the effort, as a necessary workaround for the above issue, to create a REST client that performs the add/remove/exists for queue, exchange, and bindings. So, it is safe to assume that the RMQ service is behaving correctly in the above issue. This issue is not a work stoppage for me. So, no rush. But, I expect this edge case scenario could affect others. Have a good day. |
To note, I did try slowing down logic execution to determine if the errant exception is just an eventual consistency issue for an in-progress, asynchronous binding attempt. |
Thank you for the report. What would expedite analysis is if you could provide a git repository with a complete set of code that reproduces this issue, and demonstrates your workaround. Right now you're asking us to follow some prose to guess what you're doing when a runnable project or projects (as you offered) would help tremendously. Thank you! I've been on PTO and am catching up today. |
@LeeWhite187 would you be able to provide code to run with your reproduction steps? |
Sure. I thinned out the classes enough to readily follow execution, while preserving enough abstraction, in the unit test block, to visibly align with the "prose", above. No rush on fixing it. I built a REST client as workaround. Bug me if questions, or if you need something else. |
Thank you very much! I'm working on the version 7 release and one goal is to close as many outstanding issues as possible pre-release. |
Anytime. Sorry for the delayed response, to getting you a test project to recreate the problem. Bug me if you need anything. |
@LeeWhite187 - the problem is in your Once there is an exception on a channel, you must not use it anymore, and must open a new channel. Since you continue to use the same channel in your test scenario, you see the "stale" data. Please feel free to reply if this does not seem to be the correct analysis. |
@lukebakken Thanks for your response. To clarify: Are you saying that if, for some reason, a client (of your library) requests to create a queue binding, to an exchange that doesn't exist (as is certainly possible in a large, multi-service, multi-team cluster), that the client logic MUST close the channel it used, and create a new one? What if that channel (the queue binding failed on) is associated with an existing consumer, or some other resource type? An even worse scenario, for this recovery choice, would be using the channel shared by a consumer of an exclusive queue (for a queue binding request that may fail in this way). The recovery choice you're proposing seems a little extreme in its impact, for what could be solved with logic ordering in the binding method call. With this recovery choice, I'll either have to choose to create "admin" channels for such tasking, or stick with a REST client approach (like my current workaround). Unless, I'm really using it wrong...? |
Yes, a channel-level exception from RabbitMQ requires that you close the channel. RabbitMQ will close the channel on its end. In your test scenario, you can see that Creating an "admin" channel is a good solution. |
That’s interesting to know. My tests did not include any post checks, to confirm resources remained viable. Thanks for the insight. |
Thank you. I really appreciate the effort you put into your issue description and for providing code. This feels like something that could be added to the RabbitMQ tutorials and documentation - what to do in the case of an error. |
Describe the bug
This bug is for v6.5.0 of the RabbitMQ.Client nuget package.
It's a queue binding registration problem that creates an exception on deletion of a queue.
The channel.QueueDelete method call in the .NET client library throws an exception with a message containing: 'NOT_FOUND - no exchange '.
This occurs if a previous add queue binding was attempted with an unknown exchange name.
The exception is erroneous, since the call is to delete a queue, and not an exchange.
So, that implies an orphaned reference, somewhere.... and the problem is not actually the queue delete call, directly.
It's actually that a previously executed channel.QueueBind method correctly fails with an exception for the missing exchange.
But is still allowed to register the binding (to a nonexistant exchange), before the throw.
And subsequently, when later, deleting a queue, the QueueDelete method call also throws an exception for the same missing exchange (and same exchange name).... because it discovers a binding for the missing exchange (that was allowed to be registered), even though no valid exchange existed (and the QueueBind call threw because of it).
This exception, on queue deletion, prevents the QueueDelete method logic from actually deleting the queue.
And, the queue has to be deleted via a REST call or through the management interface.
Reproduction steps
Expected behavior
The expected behavior is that:
The QueueBind method of the channel class must NOT register a binding or leave any dangling binding record when the given exchange name is not known, or the queue name is not known.
As well, the QueueDelete method of the channel must be intelligent enough to delete all bindings of the queue, regardless of exchange presence.
Also. The QueueDelete method should throw an exception for a not found queue, which it correctly does.
But, it should NOT throw an exception for a not found exchange, which is conceptually incorrect for a queue deletion.
It should gracefully cleanup any bindings without error.
Additional context
No response
The text was updated successfully, but these errors were encountered: