Skip to content

[Branch-2.8] Fix ConsumerBuilderImpl#subscribeAsync blocks calling thread. - #14614

Merged
codelipenghui merged 1 commit into
apache:branch-2.8from
Technoboy-:cherry-pick-14433
Mar 9, 2022
Merged

[Branch-2.8] Fix ConsumerBuilderImpl#subscribeAsync blocks calling thread.#14614
codelipenghui merged 1 commit into
apache:branch-2.8from
Technoboy-:cherry-pick-14433

Conversation

@Technoboy-

Copy link
Copy Markdown
Contributor

Cherry-pick #14433

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 getPartitionedTopicMetadata and then using .get() to block while waiting for the results

if (client.getPartitionedTopicMetadata(oldRetryLetterTopic)
        .get(client.conf.getOperationTimeoutMs(), TimeUnit.MILLISECONDS).partitions > 0) {
    retryLetterTopic = oldRetryLetterTopic;
}
if (client.getPartitionedTopicMetadata(oldDeadLetterTopic)
        .get(client.conf.getOperationTimeoutMs(), TimeUnit.MILLISECONDS).partitions > 0) {
    deadLetterTopic = oldDeadLetterTopic;
}

This 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 subscribeAsync on a non-blocking Pool (such as when using Netty). The signature of subscribeAsync implies that it's non-blocking. (And it seems somewhat pointless to have subscribeAsync if 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 subscribeAsync calls 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

  • Make retry and DLQ metadata async.

Documentation

  • no-need-doc

@Technoboy- Technoboy- self-assigned this Mar 9, 2022
@codelipenghui
codelipenghui merged commit d2256c8 into apache:branch-2.8 Mar 9, 2022
@codelipenghui codelipenghui added the cherry-picked/branch-2.8 Archived: 2.8 is end of life label Mar 9, 2022
nicoloboschi pushed a commit to datastax/pulsar that referenced this pull request Mar 9, 2022
@Technoboy-
Technoboy- deleted the cherry-pick-14433 branch August 10, 2022 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cherry-picked/branch-2.8 Archived: 2.8 is end of life release/2.8.4

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants