feat(spanner): add client-level CallContextConfigurator to SpannerOptions - #14256
Conversation
…ions
Adds support for configuring a client-wide CallContextConfigurator via
SpannerOptions.Builder#setCallContextConfigurator.
This allows applications (such as async and reactive pipelines where
operations span across multiple executor threads) to customize gRPC
options, timeouts, and headers across all RPCs without relying on
thread-local io.grpc.Context propagation.
Key changes:
- SpannerOptions: Added setCallContextConfigurator/getCallContextConfigurator.
SpannerCallContextTimeoutConfigurator now derives from the supplied
context rather than creating a blank default context.
- GapicSpannerRpc:
- Evaluates client-level configurator first, followed by thread-local
configurator (allowing per-call overrides).
- Reliably detects derived vs standalone delta contexts using an internal
CallOptions.Key marker, preventing extra header duplication while
preserving custom CallOptions and internal Spanner routing state.
- Wraps configurator execution exceptions in SpannerException.
- Fixed streaming reads in GapicSpannerRpc to pass getStreamingReadMethod()
instead of getReadMethod().
There was a problem hiding this comment.
Code Review
This pull request introduces support for configuring a client-level CallContextConfigurator in SpannerOptions, allowing users to apply custom gRPC options, timeouts, or credentials client-wide without relying solely on thread-local context propagation. The changes sequentially evaluate client-level and thread-level configurators, merging their options appropriately, and include comprehensive unit tests to verify these behaviors. Feedback on the implementation points out a critical issue where call credentials from a CallCredentialsProvider could be silently wiped out during a merge if a custom configurator returns a standalone delta context with custom CallOptions. A code suggestion is provided to preserve the base credentials in this scenario.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces support for configuring a client-level CallContextConfigurator in SpannerOptions, allowing users to apply custom gRPC options, timeouts, or credentials client-wide across all RPCs. It updates GapicSpannerRpc to sequentially evaluate both client-level and thread-local configurators, ensuring proper merging of contexts, options, and headers. Additionally, comprehensive unit tests have been added to verify these behaviors. As there are no review comments provided, I have no feedback to evaluate.
Adds support for configuring a client-wide CallContextConfigurator via SpannerOptions.Builder#setCallContextConfigurator.
This allows applications (such as async and reactive pipelines where operations span across multiple executor threads) to customize gRPC options, timeouts, and headers across all RPCs without relying on thread-local io.grpc.Context propagation.
Key changes: