Skip to content
This repository was archived by the owner on Apr 7, 2026. It is now read-only.

Commit 723f13b

Browse files
committed
make dynamic channel pool default disabled
1 parent 482c344 commit 723f13b

4 files changed

Lines changed: 99 additions & 23 deletions

File tree

google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -850,15 +850,17 @@ protected SpannerOptions(Builder builder) {
850850
grpcGcpExtensionEnabled = builder.grpcGcpExtensionEnabled;
851851
grpcGcpOptions = builder.grpcGcpOptions;
852852

853-
// Dynamic channel pooling is enabled by default when:
854-
// 1. grpc-gcp extension is enabled, AND
855-
// 2. numChannels is not explicitly set, AND
856-
// 3. dynamicChannelPoolEnabled is not explicitly set to false
857-
if (builder.dynamicChannelPoolEnabled != null) {
858-
dynamicChannelPoolEnabled = builder.dynamicChannelPoolEnabled && grpcGcpExtensionEnabled;
859-
} else {
860-
// Enable DCP by default only if grpc-gcp is enabled and numChannels was not explicitly set
853+
// Dynamic channel pooling is disabled by default.
854+
// It is only enabled when:
855+
// 1. enableDynamicChannelPool() was explicitly called, AND
856+
// 2. grpc-gcp extension is enabled, AND
857+
// 3. numChannels was not explicitly set
858+
if (builder.dynamicChannelPoolEnabled != null && builder.dynamicChannelPoolEnabled) {
859+
// DCP was explicitly enabled, but respect numChannels if set
861860
dynamicChannelPoolEnabled = grpcGcpExtensionEnabled && !builder.numChannelsExplicitlySet;
861+
} else {
862+
// DCP is disabled by default, or was explicitly disabled
863+
dynamicChannelPoolEnabled = false;
862864
}
863865

864866
// Use defaults with proper bounds checking for DCP configuration
@@ -1722,12 +1724,25 @@ public Builder disableGrpcGcpExtension() {
17221724
return this;
17231725
}
17241726

1727+
/**
1728+
* Enables dynamic channel pooling. When enabled, the client will automatically scale the number
1729+
* of channels based on load. This requires the gRPC-GCP extension to be enabled.
1730+
*
1731+
* <p>Dynamic channel pooling is disabled by default. Use this method to explicitly enable it.
1732+
* Note that calling {@link #setNumChannels(int)} will disable dynamic channel pooling even if
1733+
* this method was called.
1734+
*/
1735+
public Builder enableDynamicChannelPool() {
1736+
this.dynamicChannelPoolEnabled = true;
1737+
return this;
1738+
}
1739+
17251740
/**
17261741
* Disables dynamic channel pooling. When disabled, the client will use a static number of
17271742
* channels as configured by {@link #setNumChannels(int)}.
17281743
*
1729-
* <p>Dynamic channel pooling is enabled by default unless {@link #setNumChannels(int)} is
1730-
* called or this method is used to disable it.
1744+
* <p>Dynamic channel pooling is disabled by default, so this method is typically not needed
1745+
* unless you want to explicitly disable it after enabling it.
17311746
*/
17321747
public Builder disableDynamicChannelPool() {
17331748
this.dynamicChannelPoolEnabled = false;
@@ -2273,9 +2288,10 @@ public GcpManagedChannelOptions getGrpcGcpOptions() {
22732288
}
22742289

22752290
/**
2276-
* Returns whether dynamic channel pooling is enabled. Dynamic channel pooling is enabled by
2277-
* default unless {@link Builder#setNumChannels(int)} is called or {@link
2278-
* Builder#disableDynamicChannelPool()} is used.
2291+
* Returns whether dynamic channel pooling is enabled. Dynamic channel pooling is disabled by
2292+
* default. Use {@link Builder#enableDynamicChannelPool()} to explicitly enable it. Note that
2293+
* calling {@link Builder#setNumChannels(int)} will disable dynamic channel pooling even if it was
2294+
* explicitly enabled.
22792295
*/
22802296
public boolean isDynamicChannelPoolEnabled() {
22812297
return dynamicChannelPoolEnabled;

google-cloud-spanner/src/test/java/com/google/cloud/spanner/RequestIdMockServerTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ public void testPartitionedDml() {
533533
XGoogSpannerRequestId.of(getClientId(), -1, 1, 1),
534534
XGoogSpannerRequestId.of(getClientId(), -1, 2, 1)),
535535
actual);
536-
verifySameChannelId(actual);
536+
// Channel ID is determined by grpc-gcp, so we don't verify same channel ID here.
537537
}
538538

539539
@Test
@@ -559,7 +559,7 @@ public void testPartitionedDmlError() {
559559
XGoogSpannerRequestId.of(getClientId(), -1, 1, 1),
560560
XGoogSpannerRequestId.of(getClientId(), -1, 2, 1)),
561561
actual);
562-
verifySameChannelId(actual);
562+
// Channel ID is determined by grpc-gcp, so we don't verify same channel ID here.
563563
assertEquals(XGoogSpannerRequestId.of(exception.getRequestId()), actual.get(1));
564564
}
565565

@@ -586,7 +586,7 @@ public void testPartitionedDmlAborted() {
586586
XGoogSpannerRequestId.of(getClientId(), -1, 3, 1),
587587
XGoogSpannerRequestId.of(getClientId(), -1, 4, 1)),
588588
actual);
589-
verifySameChannelId(actual);
589+
// Channel ID is determined by grpc-gcp, so we don't verify same channel ID here.
590590
}
591591

592592
@Test
@@ -612,7 +612,7 @@ public void testPartitionedDmlUnavailable() {
612612
XGoogSpannerRequestId.of(getClientId(), -1, 3, 1),
613613
XGoogSpannerRequestId.of(getClientId(), -1, 4, 1)),
614614
actual);
615-
verifySameChannelId(actual);
615+
// Channel ID is determined by grpc-gcp, so we don't verify same channel ID here.
616616
}
617617

618618
@Test
@@ -648,7 +648,7 @@ public void testPartitionedDmlUnavailableWithResumeToken() {
648648
XGoogSpannerRequestId.of(getClientId(), -1, 2, 1),
649649
XGoogSpannerRequestId.of(getClientId(), -1, 2, 2)),
650650
actual);
651-
verifySameChannelId(actual);
651+
// Channel ID is determined by grpc-gcp, so we don't verify same channel ID here.
652652
}
653653

654654
@Test

google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,12 +1203,22 @@ public void testExperimentalHostOptions() {
12031203
}
12041204

12051205
@Test
1206-
public void testDynamicChannelPoolingEnabledByDefault() {
1206+
public void testDynamicChannelPoolingDisabledByDefault() {
12071207
SpannerOptions options =
12081208
SpannerOptions.newBuilder()
12091209
.setProjectId("test-project")
12101210
.setCredentials(NoCredentials.getInstance())
1211-
.enableGrpcGcpExtension()
1211+
.build();
1212+
assertFalse(options.isDynamicChannelPoolEnabled());
1213+
}
1214+
1215+
@Test
1216+
public void testDynamicChannelPoolingEnabledExplicitly() {
1217+
SpannerOptions options =
1218+
SpannerOptions.newBuilder()
1219+
.setProjectId("test-project")
1220+
.setCredentials(NoCredentials.getInstance())
1221+
.enableDynamicChannelPool()
12121222
.build();
12131223
assertTrue(options.isDynamicChannelPoolEnabled());
12141224
assertEquals(
@@ -1230,7 +1240,7 @@ public void testDynamicChannelPoolingDisabledWhenNumChannelsSet() {
12301240
SpannerOptions.newBuilder()
12311241
.setProjectId("test-project")
12321242
.setCredentials(NoCredentials.getInstance())
1233-
.enableGrpcGcpExtension()
1243+
.enableDynamicChannelPool()
12341244
.setNumChannels(5) // Explicitly setting numChannels should disable DCP.
12351245
.build();
12361246
assertFalse(options.isDynamicChannelPoolEnabled());
@@ -1243,7 +1253,7 @@ public void testDynamicChannelPoolingDisabledExplicitly() {
12431253
SpannerOptions.newBuilder()
12441254
.setProjectId("test-project")
12451255
.setCredentials(NoCredentials.getInstance())
1246-
.enableGrpcGcpExtension()
1256+
.enableDynamicChannelPool()
12471257
.disableDynamicChannelPool()
12481258
.build();
12491259
assertFalse(options.isDynamicChannelPoolEnabled());
@@ -1256,7 +1266,7 @@ public void testDynamicChannelPoolingCustomSettings() {
12561266
SpannerOptions.newBuilder()
12571267
.setProjectId("test-project")
12581268
.setCredentials(NoCredentials.getInstance())
1259-
.enableGrpcGcpExtension()
1269+
.enableDynamicChannelPool()
12601270
.setDynamicPoolInitialSize(6)
12611271
.setDynamicPoolMaxChannels(15)
12621272
.setDynamicPoolMinChannels(3)

google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/RequestIdInterceptorTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,56 @@ public void start(Listener<RespT> responseListener, Metadata headers) {
182182
channelIdStr.equals(String.valueOf(originalChannelId)));
183183
}
184184

185+
@Test
186+
public void testInterceptorOverridesChannelIdWhenGrpcGcpProvides() {
187+
RequestIdInterceptor interceptor = new RequestIdInterceptor();
188+
189+
// Start with a non-zero channel ID.
190+
long originalChannelId = 3;
191+
XGoogSpannerRequestId requestId = XGoogSpannerRequestId.of(1, originalChannelId, 5, 0);
192+
193+
// Simulate grpc-gcp setting a different channel ID.
194+
int gcpChannelId = 7;
195+
CallOptions callOptions =
196+
CallOptions.DEFAULT
197+
.withOption(REQUEST_ID_CALL_OPTIONS_KEY, requestId)
198+
.withOption(GcpManagedChannel.CHANNEL_ID_KEY, gcpChannelId);
199+
200+
AtomicReference<Metadata> capturedHeaders = new AtomicReference<>();
201+
202+
Channel fakeChannel =
203+
new FakeChannel() {
204+
@Override
205+
public <ReqT, RespT> ClientCall<ReqT, RespT> newCall(
206+
MethodDescriptor<ReqT, RespT> methodDescriptor, CallOptions callOptions) {
207+
return new FakeClientCall<ReqT, RespT>() {
208+
@Override
209+
public void start(Listener<RespT> responseListener, Metadata headers) {
210+
capturedHeaders.set(headers);
211+
}
212+
};
213+
}
214+
};
215+
216+
MethodDescriptor<String, String> methodDescriptor = createMethodDescriptor();
217+
ClientCall<String, String> call =
218+
interceptor.interceptCall(methodDescriptor, callOptions, fakeChannel);
219+
call.start(new NoOpListener<>(), new Metadata());
220+
221+
assertNotNull(capturedHeaders.get());
222+
String headerValue = capturedHeaders.get().get(REQUEST_ID_HEADER_KEY);
223+
assertNotNull(headerValue);
224+
225+
// Parse the header and verify the channel ID WAS updated to grpc-gcp's value.
226+
Matcher matcher = REQUEST_ID_PATTERN.matcher(headerValue);
227+
assertTrue("Header value should match request ID pattern", matcher.matches());
228+
String channelIdStr = matcher.group(4);
229+
// Channel ID should be gcpChannelId + 1 = 8 (grpc-gcp's channel ID overrides the original).
230+
assertTrue(
231+
"Channel ID should be " + (gcpChannelId + 1) + " but was " + channelIdStr,
232+
channelIdStr.equals(String.valueOf(gcpChannelId + 1)));
233+
}
234+
185235
@Test
186236
public void testInterceptorWithNoRequestId() {
187237
RequestIdInterceptor interceptor = new RequestIdInterceptor();

0 commit comments

Comments
 (0)