-
Notifications
You must be signed in to change notification settings - Fork 106
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
Consumer Tag Reuse Race Condition #297
Comments
Fixes jwalton#297 If consume is called before the setup function is completed, the same consumer can be registered twice and cause a precondition error.
Thanks for the detailed bug repot! |
## [4.1.7](v4.1.6...v4.1.7) (2022-09-30) ### Bug Fixes * consumer registered twice during setup ([1ca216a](1ca216a)), closes [#297](#297)
🎉 This issue has been resolved in version 4.1.7 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Thank you for the quick fix! |
Thanks for the fix! I was getting the "unknown delivery tag" on version 4.1.6 during HPA scale-up/down and by manually Force closing connections from the RabbitMQ management console BUT, What if we ack a message that was processed during a reconnection? @jwalton I hope commenting on a closed channel is ok, this is the most relevant issue and "quorum" |
We are experiencing the same issues as @TalFaitlov describes on version We are consuming messages using a single consumer from a channel, that continuously received ~20/s messages.
|
There appears to be a race condition in the
ChannelWrapper
constructor which can cause RabbitMQ to disconnect the channel with a 530 "attempt to reuse consumer tag" error when callingconsume()
. This is caused by a several factors:_onConnect
is called inside theChannelWrapper
constructor here. Since_onConnect
is async, and constructors must be synchronous, this creates a separate flow of execution disconnected from the context which called the constructor.consume
function only checks ifthis._channel
is set, and does not checkthis._settingUp
, as (for example)_shouldPublish
does.this._channel
is set before the setup promise chain is run, and that promise chain includes callingthis._reconnectConsumer
for each registered consumer. As a result, if a consumer is registered viathis.consume
between the timethis._channel
is set and the time the consumers are reconnected,this._channel.consume
will be called twice for the same consumer. This can easily happen if the setup function performs multiple operations in RabbitMQ or otherwise takes a while to complete.waitForConnect
between constructing the channel wrapper and callingconsume
, but that comes with the obvious downside of blocking the flow of execution until RabbitMQ is connected and the full channel setup is complete.Let me know if you'd like any further information. If I have time, I may put in a PR addressing factor 2 (which seems like the easiest approach to addressing the issue), but I can't guarantee that will happen any time soon.
I've put together a reproduction for the issue (which is how I noodled through everything above) which I'll include here:
Thank you!
The text was updated successfully, but these errors were encountered: