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

Commit bd64b27

Browse files
committed
respond to comments
1 parent 9eed709 commit bd64b27

2 files changed

Lines changed: 73 additions & 7 deletions

File tree

google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -361,16 +361,14 @@ public GapicSpannerRpc(final SpannerOptions options) {
361361
GrpcTransportOptions.setUpCredentialsProvider(options);
362362

363363
InstantiatingGrpcChannelProvider.Builder defaultChannelProviderBuilder =
364-
getDefaultChannelProviderBuilder(
365-
options, headerProviderWithUserAgent, isEnableDirectAccess);
364+
createChannelProviderBuilder(options, headerProviderWithUserAgent, isEnableDirectAccess);
366365

367366
if (options.getChannelProvider() == null
368367
&& isEnableDirectAccess
369368
&& isEnableGcpFallbackEnv()) {
370369
InstantiatingGrpcChannelProvider.Builder cloudPathProviderBuilder =
371-
getDefaultChannelProviderBuilder(
370+
createChannelProviderBuilder(
372371
options, headerProviderWithUserAgent, /* isEnableDirectAccess= */ false);
373-
cloudPathProviderBuilder.setAttemptDirectPath(false);
374372

375373
final AtomicReference<ManagedChannelBuilder> cloudPathBuilderRef = new AtomicReference<>();
376374
cloudPathProviderBuilder.setChannelConfigurator(
@@ -612,7 +610,6 @@ GcpFallbackChannelOptions createFallbackChannelOptions(
612610
return GcpFallbackChannelOptions.newBuilder()
613611
.setPrimaryChannelName("directpath")
614612
.setFallbackChannelName("cloudpath")
615-
.setMinFailedCalls(1)
616613
.setGcpFallbackOpenTelemetry(fallbackTelemetry)
617614
.build();
618615
}
@@ -626,7 +623,7 @@ private static String parseGrpcGcpApiConfig() {
626623
}
627624
}
628625

629-
private InstantiatingGrpcChannelProvider.Builder getDefaultChannelProviderBuilder(
626+
private InstantiatingGrpcChannelProvider.Builder createChannelProviderBuilder(
630627
final SpannerOptions options,
631628
final HeaderProvider headerProviderWithUserAgent,
632629
boolean isEnableDirectAccess) {

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

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,74 @@ public TestableGapicSpannerRpc(SpannerOptions options) {
903903
super(options);
904904
}
905905

906+
@Override
907+
GcpFallbackChannelOptions createFallbackChannelOptions(
908+
GcpFallbackOpenTelemetry fallbackTelemetry) {
909+
// Override default 1-minute period to 10ms for instant testing
910+
return GcpFallbackChannelOptions.newBuilder()
911+
.setPrimaryChannelName("directpath")
912+
.setFallbackChannelName("cloudpath")
913+
.setPeriod(Duration.ofMillis(10))
914+
.setGcpFallbackOpenTelemetry(fallbackTelemetry)
915+
.build();
916+
}
917+
}
918+
919+
@Test
920+
public void testFallbackIntegration_doesNotSwitchWhenThresholdNotMet() throws Exception {
921+
GapicSpannerRpc.enableGcpFallbackEnv = true;
922+
923+
// Setup OpenTelemetry to capture metrics
924+
InMemoryMetricReader metricReader = InMemoryMetricReader.create();
925+
SdkMeterProvider meterProvider =
926+
SdkMeterProvider.builder().registerMetricReader(metricReader).build();
927+
OpenTelemetrySdk openTelemetry =
928+
OpenTelemetrySdk.builder().setMeterProvider(meterProvider).build();
929+
930+
// Setup Options with invalid host to force error
931+
SpannerOptions options =
932+
SpannerOptions.newBuilder()
933+
.setProjectId("test-project")
934+
.setEnableDirectAccess(true)
935+
.setHost("http://localhost:1") // Closed port
936+
.setCredentials(NoCredentials.getInstance())
937+
.setOpenTelemetry(openTelemetry)
938+
.build();
939+
940+
TestableGapicSpannerRpc rpc = new TestableGapicSpannerRpc(options);
941+
942+
try {
943+
// Make a call that is expected to fail
944+
try {
945+
rpc.executeBatchDml(
946+
com.google.spanner.v1.ExecuteBatchDmlRequest.newBuilder()
947+
.setSession("projects/p/instances/i/databases/d/sessions/s")
948+
.build(),
949+
null);
950+
} catch (Exception expected) {
951+
// Expect a connection error
952+
}
953+
954+
// Wait briefly for the 10ms period to trigger the fallback check
955+
Thread.sleep(100);
956+
957+
// Verify Fallback via Metrics
958+
Collection<MetricData> metrics = metricReader.collectAllMetrics();
959+
boolean fallbackOccurred =
960+
metrics.stream().anyMatch(md -> md.getName().contains("fallback_count") && hasValue(md));
961+
962+
assertFalse("Fallback metric should not be present", fallbackOccurred);
963+
964+
} finally {
965+
rpc.shutdown();
966+
}
967+
}
968+
969+
static class TestableGapicSpannerRpcWithLowerMinFailedCalls extends GapicSpannerRpc {
970+
public TestableGapicSpannerRpcWithLowerMinFailedCalls(SpannerOptions options) {
971+
super(options);
972+
}
973+
906974
@Override
907975
GcpFallbackChannelOptions createFallbackChannelOptions(
908976
GcpFallbackOpenTelemetry fallbackTelemetry) {
@@ -938,7 +1006,8 @@ public void testFallbackIntegration_switchesToFallbackOnFailure() throws Excepti
9381006
.setOpenTelemetry(openTelemetry)
9391007
.build();
9401008

941-
TestableGapicSpannerRpc rpc = new TestableGapicSpannerRpc(options);
1009+
TestableGapicSpannerRpcWithLowerMinFailedCalls rpc =
1010+
new TestableGapicSpannerRpcWithLowerMinFailedCalls(options);
9421011

9431012
try {
9441013
// Make a call that is expected to fail

0 commit comments

Comments
 (0)