Skip to content

HBASE-28792: AsyncTableImpl should call coprocessor callbacks in a defined order - #6168

Merged
ndimiduk merged 5 commits into
apache:masterfrom
HubSpot:asynctableimpl-coproc-callback
Sep 4, 2024
Merged

HBASE-28792: AsyncTableImpl should call coprocessor callbacks in a defined order#6168
ndimiduk merged 5 commits into
apache:masterfrom
HubSpot:asynctableimpl-coproc-callback

Conversation

@charlesconnell

@charlesconnellcharlesconnell commented Aug 20, 2024

Copy link
Copy Markdown
Contributor

To call a coprocessor endpoint asynchronously, you start by calling AsyncTable#coprocessorService(), which gives you a CoprocessorServiceBuilder, and a few steps later you can talk to your coprocessor over the network. One argument to AsyncTable#coprocessorService() is a CoprocessorCallback object, which contains several methods that will be called during the lifecycle of a coprocessor endpoint call. AsyncTableImpl's implementation of AsyncTable#coprocessorService() wraps your CoprocessorCallback with its own that delegates the work to a thread pool. A snippet of this:

 @Override
public void onRegionComplete(RegionInfo region, R resp) {
pool.execute(context.wrap(() -> callback.onRegionComplete(region, resp)));
}
...
@Override
public void onComplete() {
pool.execute(context.wrap(callback::onComplete));
}

The trouble with this is that your implementations of onRegionComplete() and onComplete() will end up getting called in a random order, and/or at the same time. The tasks of calling them are delegated to a thread pool, and the completion of those tasks is not waited on, so the thread pool can choose any ordering it wants to. Troublingly, onComplete() can be called before the final onRegionComplete(), which is an violation of the contract specified in the CoprocessorCallback#onComplete() javadoc.

This PR eliminates the use of a thread pool for calling the coprocessor callback, and calls them directly on the thread that received the response from the server.

@Apache-HBase

This comment has been minimized.

@charlesconnell
charlesconnellforce-pushed the asynctableimpl-coproc-callback branch from fee3060 to 02b99bcCompareAugust 20, 2024 14:16
@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache9

Copy link
Copy Markdown
Contributor

The intention here is that, in AsyncTableImpl, we will always call any callbacks in a thread pool, in order to prevent blocking operations in callbacks blocking the system thread(like netty event loop). If you want high performance, you can use RawAsyncTable directly.

Here I think we should still use the thread pool, but use some tricks to let onComplete to be called at last.

Thanks.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@charlesconnell

Copy link
Copy Markdown
ContributorAuthor

@Apache9 Understood. I've brought back the thread pool usage and added a barrier to force onComplete() to wait until onRegionComplete() is done.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@ndimidukndimiduk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Duo about the threadpool bit. I think this Phaser approach works fine. I'm curious if there's a "better" implementation based on chaining CompletableFutures ... I'll need to spend some time with the APIs to see if I have a suggestion.

@ndimidukndimiduk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So unfortunately our CoprocessorCallback API seems to completely preclude use of the CompletableFuture chaining strategy. I think you're on the right path here.

pool.execute(context.wrap(callback::onComplete));
pool.execute(context.wrap(() -> {
// Guarantee that onComplete() is called after all onRegionComplete()'s are called
regionCompletesInProgress.arriveAndAwaitAdvance();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the Javadoc on this method, onComplete must implement a happens-after semantic for all onRegionComplete and all onRegionError invocations. This implies that there are multiple regions to complete AND multiple forms of completion, so I think that this can be solved with a phaser ; you need a more general purpose mutex.

@charlesconnellcharlesconnellSep 2, 2024

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point that onRegionError should be included in the barrier. I'm guessing you meant to say "so I think that this cannot be solved with a phaser," but I disagree. The phaser can be used in onRegionError just the same as onRegionComplete.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see. Phaser is more powerful than I initially understood -- very cool! Yes, this looks better to me.

@Apache-HBase

Copy link
Copy Markdown

🎊 +1 overall

VoteSubsystemRuntimeLogfileComment
+0 🆗reexec0m 26sDocker mode activated.
-0 ⚠️yetus0m 3sUnprocessed flag(s): --brief-report-file --spotbugs-strict-precheck --author-ignore-list --blanks-eol-ignore-file --blanks-tabs-ignore-file --quick-hadoopcheck
_ Prechecks _
_ master Compile Tests _
+0 🆗mvndep0m 38sMaven dependency ordering for branch
+1 💚mvninstall3m 17smaster passed
+1 💚compile0m 38smaster passed
+1 💚javadoc0m 27smaster passed
+1 💚shadedjars5m 34sbranch has no errors when building our shaded downstream artifacts.
_ Patch Compile Tests _
+0 🆗mvndep0m 12sMaven dependency ordering for patch
+1 💚mvninstall2m 55sthe patch passed
+1 💚compile0m 37sthe patch passed
+1 💚javac0m 37sthe patch passed
+1 💚javadoc0m 26sthe patch passed
+1 💚shadedjars5m 36spatch has no errors when building our shaded downstream artifacts.
_ Other Tests _
+1 💚unit1m 36shbase-client in the patch passed.
+1 💚unit3m 31shbase-endpoint in the patch passed.
27m 9s
SubsystemReport/Notes
DockerClientAPI=1.43 ServerAPI=1.43 base: https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-6168/6/artifact/yetus-jdk17-hadoop3-check/output/Dockerfile
GITHUB PR#6168
JIRA IssueHBASE-28792
Optional Testsjavac javadoc unit compile shadedjars
unameLinux 1e9ab3d364db 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Build toolmaven
Personalitydev-support/hbase-personality.sh
git revisionmaster / 5573a60
Default JavaEclipse Adoptium-17.0.11+9
Test Resultshttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-6168/6/testReport/
Max. process+thread count1383 (vs. ulimit of 30000)
modulesC: hbase-client hbase-endpoint U: .
Console outputhttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-6168/6/console
versionsgit=2.34.1 maven=3.9.8
Powered byApache Yetus 0.15.0 https://yetus.apache.org

This message was automatically generated.

@Apache-HBase

Copy link
Copy Markdown

🎊 +1 overall

VoteSubsystemRuntimeLogfileComment
+0 🆗reexec0m 31sDocker mode activated.
_ Prechecks _
+1 💚dupname0m 0sNo case conflicting files found.
+0 🆗codespell0m 0scodespell was not available.
+0 🆗detsecrets0m 0sdetect-secrets was not available.
+1 💚@author0m 0sThe patch does not contain any @author tags.
+1 💚hbaseanti0m 0sPatch does not have any anti-patterns.
_ master Compile Tests _
+0 🆗mvndep0m 10sMaven dependency ordering for branch
+1 💚mvninstall3m 30smaster passed
+1 💚compile1m 27smaster passed
+1 💚checkstyle0m 31smaster passed
+1 💚spotbugs1m 26smaster passed
+1 💚spotless0m 59sbranch has no errors when running spotless:check.
_ Patch Compile Tests _
+0 🆗mvndep0m 11sMaven dependency ordering for patch
+1 💚mvninstall3m 21sthe patch passed
+1 💚compile1m 23sthe patch passed
+1 💚javac1m 23sthe patch passed
+1 💚blanks0m 0sThe patch has no blanks issues.
+1 💚checkstyle0m 29sthe patch passed
+1 💚spotbugs1m 35sthe patch passed
+1 💚hadoopcheck12m 13sPatch does not cause any errors with Hadoop 3.3.6 3.4.0.
+1 💚spotless0m 53spatch has no errors when running spotless:check.
_ Other Tests _
+1 💚asflicense0m 21sThe patch does not generate ASF License warnings.
36m 49s
SubsystemReport/Notes
DockerClientAPI=1.43 ServerAPI=1.43 base: https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-6168/6/artifact/yetus-general-check/output/Dockerfile
GITHUB PR#6168
JIRA IssueHBASE-28792
Optional Testsdupname asflicense javac spotbugs checkstyle codespell detsecrets compile hadoopcheck hbaseanti spotless
unameLinux 8ada949607ee 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Build toolmaven
Personalitydev-support/hbase-personality.sh
git revisionmaster / 5573a60
Default JavaEclipse Adoptium-17.0.11+9
Max. process+thread count82 (vs. ulimit of 30000)
modulesC: hbase-client hbase-endpoint U: .
Console outputhttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-6168/6/console
versionsgit=2.34.1 maven=3.9.8 spotbugs=4.7.3
Powered byApache Yetus 0.15.0 https://yetus.apache.org

This message was automatically generated.

@ndimidukndimiduk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fix.

pool.execute(context.wrap(callback::onComplete));
pool.execute(context.wrap(() -> {
// Guarantee that onComplete() is called after all onRegionComplete()'s are called
regionCompletesInProgress.arriveAndAwaitAdvance();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see. Phaser is more powerful than I initially understood -- very cool! Yes, this looks better to me.

@ndimiduk
ndimiduk merged commit 63b26b1 into apache:masterSep 4, 2024
@ndimiduk
ndimiduk deleted the asynctableimpl-coproc-callback branch September 4, 2024 07:49
ndimiduk pushed a commit to ndimiduk/hbase that referenced this pull request Sep 4, 2024
…fined order (apache#6168)
Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
ndimiduk pushed a commit to ndimiduk/hbase that referenced this pull request Sep 4, 2024
…fined order (apache#6168)
Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
@Apache9

Copy link
Copy Markdown
Contributor

Ah, just 5 minutes late...

LGTM.

Thanks @charlesconnell and @ndimiduk !

ndimiduk pushed a commit to ndimiduk/hbase that referenced this pull request Sep 4, 2024
…fined order (apache#6168)
Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
ndimiduk pushed a commit to ndimiduk/hbase that referenced this pull request Sep 4, 2024
…fined order (apache#6168)
Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
@ndimiduk

Copy link
Copy Markdown
Member

All good. Welcome back @Apache9 !

ndimiduk pushed a commit that referenced this pull request Sep 4, 2024
…fined order (#6168)
Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
ndimiduk added a commit that referenced this pull request Sep 4, 2024
…ks in a defined order (#6168)" to branch-2 (#6200)
Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
Co-authored-by: Charles Connell <cconnell@hubspot.com>
ndimiduk added a commit that referenced this pull request Sep 4, 2024
…fined order (#6168)
Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
Co-authored-by: Charles Connell <cconnell@hubspot.com>
ndimiduk added a commit that referenced this pull request Sep 4, 2024
…fined order (#6168)
Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
Co-authored-by: Charles Connell <cconnell@hubspot.com>
ndimiduk added a commit that referenced this pull request Sep 4, 2024
…fined order (#6168)
Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
Co-authored-by: Charles Connell <cconnell@hubspot.com>
sanjeet006py pushed a commit to sanjeet006py/hbase that referenced this pull request Aug 24, 2025
…fined order (apache#6168)
Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
Co-authored-by: Charles Connell <cconnell@hubspot.com>
Sign up for freeto 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.

4 participants

@charlesconnell@Apache-HBase@Apache9@ndimiduk