| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
This PR enables the gRPC-GCP channel pool extension by default for Cloud Spanner Java client.
**What's Changing for Customers**
**Before this change**
- gRPC-GCP extension was disabled by default
- Default number of channels: 4
- Channel pooling was handled by GAX
**After this change**
- gRPC-GCP extension is enabled by default
- Default number of channels: 8
- Channel pooling is handled by gRPC-GCP extension
**Benefits of gRPC-GCP**
- **Improved resilience:** When a network connection fails on a particular channel, operations can be automatically retried on a different gRPC channel
- **Better channel management:** gRPC-GCP provides more sophisticated channel affinity and load balancing
**How to Disable gRPC-GCP (Switch Back to GAX Channel Pool)**
If you need to disable gRPC-GCP and use the previous GAX channel pooling behavior, use the `disableGrpcGcpExtension()` method:
```
SpannerOptions options = SpannerOptions.newBuilder()
.setProjectId("my-project")
.disableGrpcGcpExtension()
.build();
```
When disabled, the default number of channels reverts to 4 (the previous default).
**When You Might Want to Disable gRPC-GCP**
- **Maintaining previous behavior:** If you want to keep the exact same behavior as before this change (GAX channel pool with 4 default channels).
- **Troubleshooting**: If you experience any unexpected behavior, disabling gRPC-GCP can help isolate whether the issue is related to the channel pooling mechanism.
The static-pool path bounded the affinity key to (-numChannels..numChannels) distinct values. Under a high-concurrency cold start, all keys race through GcpManagedChannel.pickLeastBusyChannel before any caller's start() has incremented activeStreamsCount, so they all tie to channelRefs[0] and bind there permanently. The result is most RPCs route through a single HTTP/2 connection and queue at MAX_CONCURRENT_STREAMS (~100), capping per-client throughput. Regression became default-path behavior in 6.105.0 (googleapis#4239). With multiplexed sessions there is no per-transaction locality benefit from sticky channel affinity. Dropping the key for the static-pool case makes GcpManagedChannel.getChannelRef(null) do a fresh per-call least-busy pick with no sticky bind, which self-corrects and matches the dynamic-pool / disableGrpcGcpExtension() throughput curve.
Under grpc-gcp (default since 6.105.0, googleapis#4239), newCallContext set GcpManagedChannel.AFFINITY_KEY on every data RPC. GcpManagedChannel binds each new key via pickLeastBusyChannel, which reads activeStreamsCount before any concurrent caller's start() has incremented it (tiebreak channelRefs[0]). A high-concurrency cold start therefore binds keys to channel 0 and the bindings are sticky, so RPCs funnel through one HTTP/2 connection and queue at MAX_CONCURRENT_STREAMS. The static-numChannels path bounded the key to ~2*numChannels-1 distinct values, making the collapse permanent (~6x throughput regression at 400 concurrent). The dynamic-channel-pool path used per-transaction random keys and largely self-corrected, but a few BitSet-recycled hints still sticky-bound, leaving a p99 tail. Multiplexed sessions get no backend-locality benefit from sticky per-transaction channel affinity, so don't set the key under grpc-gcp at all. getChannelRef(null) does a fresh per-call least-busy pick with no sticky binding and no affinity-map growth. Drops the now-unobservable distinct-AFFINITY_KEY assertions from RetryOnDifferentGrpcChannelMockServerTest; the request-count and session assertions still cover the retry loop.
| Back | FazBrowse Home | New Git URL |
This PR was generated using Autosynth. 🌈
Here's the log from Synthtool: