Threading refactor (3/7): Executor isolation by igorbernstein2 · Pull Request #3 · igorbernstein2/google-cloud-java · GitHub
Skip to content

Threading refactor (3/7): Executor isolation#3

Open
igorbernstein2 wants to merge 5 commits into
threading-refactor-phase-2from
threading-refactor-phase-3
Open

Threading refactor (3/7): Executor isolation#3
igorbernstein2 wants to merge 5 commits into
threading-refactor-phase-2from
threading-refactor-phase-3

Conversation

@igorbernstein2

Copy link
Copy Markdown
Owner

Summary

Phase 3 of 7. Decouples thread pools so that a blocked user callback can't starve session bookkeeping, and pushes the per-op executor onto a serializing path off the shared user-callback pool.

What's in here

Commit What it does
chore: isolate user-callback executor on a cached thread pool Client (and ShimImpl) own a dedicated bigtable-callback-%d cached pool, plumbed through *Async / TableBase. A blocked user callback can no longer
starve heartbeats, retry delays, or pool bookkeeping (all of which run on backgroundExecutor).
chore: back OpExecutor with SerializingExecutor(userCallbackExecutor) VOperationImpl now constructs OpExecutor over a per-call SequentialExecutor on the shared userCallbackExecutor, replacing the per-call
SynchronizationContext. OpExecutor gains an UncaughtExceptionHandler ctor arg — the safety net the removed RetryingVRpc-owned SyncContext provided.
chore: configure gRPC session streams with DirectExecutor CallOptions.withExecutor(MoreExecutors.directExecutor()) on the session stream so Netty I/O threads deliver SessionStream.Listener callbacks directly;
sessionSyncContext immediately trampolines off them.

Stack position

  • Base: threading-refactor-phase-2
  • Next: threading-refactor-phase-4 — pool & op-executor contract

@igorbernstein2 igorbernstein2 force-pushed the threading-refactor-phase-3 branch from 8f18528 to b32ff78 Compare June 17, 2026 20:02
@igorbernstein2 igorbernstein2 force-pushed the threading-refactor-phase-2 branch from a702c4e to 0f6a9e4 Compare June 17, 2026 20:02
featureFlags = featureFlags.toBuilder().setSessionsRequired(true).build();
}

java.util.concurrent.ExecutorService userCallbackExecutor =

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

why do we need to create one here. Is there any problem always create that in the Client only?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

The intent is to extract it from the gax InstantiatingGrpcChannelProvider/StubSettings in case the user overrode it

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I see the handler here is no-op for tests. But to make sure we can only use this method in tests maybe change it to package-private?

Client (and ShimImpl) own a dedicated bigtable-callback-%d cached pool,
plumbed through *Async / TableBase. A blocked user callback can no longer
starve heartbeats, retry delays, or pool bookkeeping (all of which run on
backgroundExecutor). The op-level SerializingExecutor in a later commit
will dispatch onto this pool.
VOperationImpl now constructs OpExecutor over a per-call SequentialExecutor
on the shared userCallbackExecutor, replacing the per-call
SynchronizationContext. OpExecutor gains an UncaughtExceptionHandler ctor
arg — the safety net that the removed RetryingVRpc-owned SyncContext
provided. The 3-arg VRpcCallContext.create defaults to a no-op handler for
tests; production callers go through VOperationImpl.
CallOptions.withExecutor(MoreExecutors.directExecutor()) on the session
stream so Netty I/O threads deliver SessionStream.Listener callbacks
directly; sessionSyncContext immediately trampolines off them.
@igorbernstein2 igorbernstein2 force-pushed the threading-refactor-phase-2 branch from 0f6a9e4 to 932ad80 Compare June 22, 2026 21:41
@igorbernstein2 igorbernstein2 force-pushed the threading-refactor-phase-3 branch from b32ff78 to 5c4f476 Compare June 22, 2026 21:41
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.

3 participants