Skip to content

Conversation

@rahul2393
Copy link
Contributor

@rahul2393 rahul2393 commented Dec 15, 2025

Description

This PR adds support for Dynamic Channel Pooling (DCP), which enables automatic scaling of gRPC channels based on load.

Dynamic Channel Pool is disabled by default and must be explicitly enabled via enableDynamicChannelPool(). DCP will be enabled by default in a future release.

Basic Usage (with Spanner defaults)

SpannerOptions options = SpannerOptions.newBuilder()
    .setProjectId("my-project")
    .enableDynamicChannelPool()  // Required to enable DCP
    .build();

Custom Configuration

For custom configuration, use setGcpChannelPoolOptions(GcpChannelPoolOptions):

SpannerOptions options = SpannerOptions.newBuilder()
    .setProjectId("my-project")
    .enableDynamicChannelPool()
    .setGcpChannelPoolOptions(
        GcpChannelPoolOptions.newBuilder()
            .setMaxSize(15)
            .setMinSize(3)
            .setInitSize(5)
            .setDynamicScaling(10, 30, Duration.ofMinutes(5))
            .setAffinityKeyLifetime(Duration.ofMinutes(10))
            .setCleanupInterval(Duration.ofMinutes(1))
            .build())
    .build();

Spanner Default Configuration

When enableDynamicChannelPool() is called without custom GcpChannelPoolOptions, Spanner-specific defaults are applied via SpannerOptions.createDefaultDynamicChannelPoolOptions():

Option Default Description
Max Size 10 Maximum channels (won't scale above)
Min Size 2 Minimum channels (won't scale below)
Initial Size 4 Initial number of channels
Max RPC/Channel 25 RPCs/channel threshold to scale up
Min RPC/Channel 15 RPCs/channel threshold to scale down
Scale Down Interval 3 min How often to check for scale down
Affinity Key Lifetime 10 min TTL for affinity keys
Cleanup Interval 1 min Cleanup frequency for stale keys

API Summary

Method Description
enableDynamicChannelPool() Enables dynamic channel pooling
disableDynamicChannelPool() Disables dynamic channel pooling
isDynamicChannelPoolEnabled() Returns whether DCP is enabled
setGcpChannelPoolOptions(GcpChannelPoolOptions) Sets custom channel pool options
getGcpChannelPoolOptions() Returns the channel pool options
SpannerOptions.createDefaultDynamicChannelPoolOptions() Static factory for Spanner defaults

Behavior Notes

  • DCP requires gRPC-GCP extension (enabled by default)
  • Calling setNumChannels(int) disables DCP even if explicitly enabled
  • Channel IDs in request headers (e.g., X-Goog-Spanner-Request-Id) now reflect the actual physical channel selected by grpc-gcp, rather than the logical channel hint computed by the client
  • Validation of channel pool options (min/max channels, RPC thresholds, etc.) is delegated to grpc-gcp's GcpChannelPoolOptions.Builder

@rahul2393 rahul2393 requested review from a team as code owners December 15, 2025 11:31
@product-auto-label product-auto-label bot added size: l Pull request size is large. api: spanner Issues related to the googleapis/java-spanner API. labels Dec 15, 2025
@gemini-code-assist

This comment was marked as outdated.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for dynamic channel pooling in the Spanner client, which is a significant enhancement. The changes are well-structured across configuration (SpannerOptions), RPC implementation (GapicSpannerRpc), and interceptors (RequestIdInterceptor). The feature is controlled by a comprehensive set of new options, with sensible defaults and validation. The inclusion of extensive unit tests for both the new options and the interceptor logic is commendable. My review includes a couple of suggestions to improve robustness and align the implementation with the documented behavior.

@rahul2393 rahul2393 force-pushed the dynamic-channel-pool-support branch from da0405a to 33a2af2 Compare December 16, 2025 09:39
@product-auto-label product-auto-label bot added size: xl Pull request size is extra large. and removed size: l Pull request size is large. labels Dec 16, 2025
@rahul2393 rahul2393 requested a review from olavloite December 16, 2025 10:06
@rahul2393 rahul2393 force-pushed the dynamic-channel-pool-support branch from 78c37c7 to 723f13b Compare December 16, 2025 10:29
@rahul2393 rahul2393 force-pushed the dynamic-channel-pool-support branch from 723f13b to ce43d4a Compare December 16, 2025 10:53

// When dynamic channel pool is enabled, use the DCP initial size as the pool size.
// When disabled, use the explicitly configured numChannels.
final int poolSize = options.isDynamicChannelPoolEnabled() ? 0 : options.getNumChannels();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this change the behavior for customers who are currently using grpc-gcp? (I would think not, considering that it seems like the channel pool size was set to options.getNumChannels() before this change as well)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, because when poolSize = 0, grpc-gcp uses initSize from GcpChannelPoolOptions. Previously, numChannels was used as the pool size. The change is intentional to let DCP control initialization.

@product-auto-label product-auto-label bot added size: l Pull request size is large. and removed size: xl Pull request size is extra large. labels Dec 16, 2025
@rahul2393 rahul2393 requested a review from olavloite December 16, 2025 15:48
@rahul2393 rahul2393 added the automerge Merge the pull request once unit tests and other checks pass. label Dec 16, 2025
@olavloite olavloite merged commit 923a14a into main Dec 16, 2025
59 of 60 checks passed
@olavloite olavloite deleted the dynamic-channel-pool-support branch December 16, 2025 17:45
@gcf-merge-on-green gcf-merge-on-green bot removed the automerge Merge the pull request once unit tests and other checks pass. label Dec 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: spanner Issues related to the googleapis/java-spanner API. size: l Pull request size is large.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants