Skip to content
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

GH-2653: Fix deadlock in the DirectMessageListenerContainer #2655

Merged
merged 2 commits into from
Mar 18, 2024

Conversation

artembilan
Copy link
Member

Fixes: #2653

When not enough channel in the cache, the DirectMessageListenerContainer.consume() returns null and adjustConsumers() goes into an infinite loop, since already active consumer does not release its channel.

  • Fix DirectMessageListenerContainer.consume() to re-throw an AmqpTimeoutException which is thrown when no available channels in the cache
  • Catch AmqpTimeoutException in the DirectReplyToMessageListenerContainer.getChannelHolder() and reset this.consumerCount-- to allow to try existing consumer until it is available, e.g. when this one receives a reply or times out.

…ainer

Fixes: spring-projects#2653

When not enough channel in the cache, the `DirectMessageListenerContainer.consume()`
returns null and `adjustConsumers()` goes into an infinite loop, since already active
consumer does not release its channel.

* Fix `DirectMessageListenerContainer.consume()` to re-throw an `AmqpTimeoutException`
which is thrown when no available channels in the cache
* Catch `AmqpTimeoutException` in the `DirectReplyToMessageListenerContainer.getChannelHolder()`
and reset `this.consumerCount--` to allow to try existing consumer until it is available, e.g.
when this one receives a reply or times out.
@utikeev
Copy link

utikeev commented Mar 15, 2024

Is it safe to update consumerCount without a lock (or at least non-atomically)?
I mean, don't processMonitorTask and getChannelHolder execute on different threads? Even with just getChannelHolder being executed on different threads one can receive an incorrect count.

@artembilan
Copy link
Member Author

@utikeev ,

thank you for the pointer!
So, changed that consumerCount to an AtomicInteger.
The point of the fix is to keep that super.setConsumersPerQueue() out of the lock.

@artembilan
Copy link
Member Author

Merging this into main for today's release.
At least this fixes an immediate dead-lock problem.
Anything else we can revise later when it arises.

Thanks

@artembilan artembilan merged commit b19fa8c into spring-projects:main Mar 18, 2024
3 checks passed
@artembilan artembilan deleted the GH-2653 branch May 31, 2024 19:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deadlock when reaching channel limit in DirectMessageListenerContainer
3 participants