Fix ConsumerBuilderImpl#subscribeAsync blocks calling thread. - #14433
Conversation
Jason918
left a comment
There was a problem hiding this comment.
Overall LGTM.
I wonder if it's possible that we can add some kind of client version check to avoid this compatibility check?
Perhaps a flag on
|
Yes, we can open a new issue for discussion. |
|
@Jason918 @codelipenghui @gaoran10 @mattisonchao |
(cherry picked from commit 7a58aeb)
(cherry picked from commit 7a58aeb)
|
@Technoboy- Please provide a correct documentation label for your PR. |
Fixes #14413
Motivation
When Retry topics are enabled, ConsumerBuilderImpl performs a backwards-compatibility check to look for DLQ or Retry topics that were created on previous version of Pulsar using a different naming scheme.
It does this by calling
getPartitionedTopicMetadataand then using.get()to block while waiting for the resultsThis was implemented in #10129
A partial fix to add a Timeout was implemented in #11597
However this fix does still block the calling thread during the lookup.
This can be an issue for code that attempt to call
subscribeAsyncon a non-blocking Pool (such as when using Netty). The signature ofsubscribeAsyncimplies that it's non-blocking. (And it seems somewhat pointless to havesubscribeAsyncif it blocks anyway)Note that this is an undocumented breaking change in behavior. Up until 2.9, it was safe to call this from a non-blocking pool.
In our case, we were running a custom SLF4J log exporter on the same thread pool, which resulted in a deadlock when the number of concurrent
subscribeAsynccalls exceeded the pool size. (This is probably an extreme example and a poor decision on our part, but perhaps a good example of why unexpected blocking can be dangerous)Note that blocking call is still made even if the retry and DLQ names are explicitly specified in DeadLetterPolicy. In that scenario the check should not be needed. Aside from blocking the calling Thread, this also results in unneeded lookup requests.
Modifications
Documentation
no-need-doc