Skip to content

Commit 84e0d18

Browse files
authored
chore(spanner): Auto-enable location API and dynamic channel pool for experimental hosts (#12679)
2 parents aca0428 + d658bcd commit 84e0d18

File tree

1 file changed

+68
-10
lines changed

1 file changed

+68
-10
lines changed

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

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public class SpannerOptions extends ServiceOptions<Spanner, SpannerOptions> {
141141

142142
// Dynamic Channel Pool (DCP) default values and bounds
143143
/** Default max concurrent RPCs per channel before triggering scale up. */
144-
public static final int DEFAULT_DYNAMIC_POOL_MAX_RPC = 25;
144+
public static final int DEFAULT_DYNAMIC_POOL_MAX_RPC = 90;
145145

146146
/** Default min concurrent RPCs per channel for scale down check. */
147147
public static final int DEFAULT_DYNAMIC_POOL_MIN_RPC = 15;
@@ -150,13 +150,13 @@ public class SpannerOptions extends ServiceOptions<Spanner, SpannerOptions> {
150150
public static final Duration DEFAULT_DYNAMIC_POOL_SCALE_DOWN_INTERVAL = Duration.ofMinutes(3);
151151

152152
/** Default initial number of channels for dynamic pool. */
153-
public static final int DEFAULT_DYNAMIC_POOL_INITIAL_SIZE = 4;
153+
public static final int DEFAULT_DYNAMIC_POOL_INITIAL_SIZE = 1;
154154

155155
/** Default max number of channels for dynamic pool. */
156-
public static final int DEFAULT_DYNAMIC_POOL_MAX_CHANNELS = 10;
156+
public static final int DEFAULT_DYNAMIC_POOL_MAX_CHANNELS = 256;
157157

158158
/** Default min number of channels for dynamic pool. */
159-
public static final int DEFAULT_DYNAMIC_POOL_MIN_CHANNELS = 2;
159+
public static final int DEFAULT_DYNAMIC_POOL_MIN_CHANNELS = 1;
160160

161161
/**
162162
* Default affinity key lifetime for dynamic channel pool. This is how long to keep an affinity
@@ -204,6 +204,49 @@ public static GcpChannelPoolOptions createDefaultDynamicChannelPoolOptions() {
204204
.build();
205205
}
206206

207+
/**
208+
* Merges user-provided {@link GcpChannelPoolOptions} with Spanner-specific defaults. Any value
209+
* that the user has not explicitly set (i.e. left at the builder's default of 0 or null) will be
210+
* filled in from {@link #createDefaultDynamicChannelPoolOptions()}.
211+
*/
212+
static GcpChannelPoolOptions mergeWithDefaultChannelPoolOptions(
213+
GcpChannelPoolOptions userOptions) {
214+
GcpChannelPoolOptions defaults = createDefaultDynamicChannelPoolOptions();
215+
GcpChannelPoolOptions.Builder merged = GcpChannelPoolOptions.newBuilder(userOptions);
216+
if (userOptions.getMaxSize() <= 0) {
217+
merged.setMaxSize(defaults.getMaxSize());
218+
}
219+
if (userOptions.getMinSize() <= 0) {
220+
merged.setMinSize(defaults.getMinSize());
221+
}
222+
if (userOptions.getInitSize() <= 0) {
223+
merged.setInitSize(defaults.getInitSize());
224+
}
225+
if (userOptions.getMinRpcPerChannel() <= 0
226+
|| userOptions.getMaxRpcPerChannel() <= 0
227+
|| userOptions.getScaleDownInterval() == null
228+
|| userOptions.getScaleDownInterval().isZero()) {
229+
merged.setDynamicScaling(
230+
userOptions.getMinRpcPerChannel() > 0
231+
? userOptions.getMinRpcPerChannel()
232+
: defaults.getMinRpcPerChannel(),
233+
userOptions.getMaxRpcPerChannel() > 0
234+
? userOptions.getMaxRpcPerChannel()
235+
: defaults.getMaxRpcPerChannel(),
236+
userOptions.getScaleDownInterval() != null && !userOptions.getScaleDownInterval().isZero()
237+
? userOptions.getScaleDownInterval()
238+
: defaults.getScaleDownInterval());
239+
}
240+
if (userOptions.getAffinityKeyLifetime() == null
241+
|| userOptions.getAffinityKeyLifetime().isZero()) {
242+
merged.setAffinityKeyLifetime(defaults.getAffinityKeyLifetime());
243+
}
244+
if (userOptions.getCleanupInterval() == null || userOptions.getCleanupInterval().isZero()) {
245+
merged.setCleanupInterval(defaults.getCleanupInterval());
246+
}
247+
return merged.build();
248+
}
249+
207250
private final TransportChannelProvider channelProvider;
208251
private final ChannelEndpointCacheFactory channelEndpointCacheFactory;
209252

@@ -881,21 +924,29 @@ protected SpannerOptions(Builder builder) {
881924

882925
// Dynamic channel pooling is disabled by default.
883926
// It is only enabled when:
884-
// 1. enableDynamicChannelPool() was explicitly called, AND
927+
// 1. enableDynamicChannelPool() was explicitly called (or experimentalHost is set and DCP was
928+
// not explicitly disabled), AND
885929
// 2. grpc-gcp extension is enabled, AND
886930
// 3. numChannels was not explicitly set
887-
if (builder.dynamicChannelPoolEnabled != null && builder.dynamicChannelPoolEnabled) {
888-
// DCP was explicitly enabled, but respect numChannels if set
931+
boolean dcpRequested =
932+
builder.dynamicChannelPoolEnabled != null
933+
? builder.dynamicChannelPoolEnabled
934+
: builder.experimentalHost != null;
935+
if (dcpRequested) {
936+
// DCP was enabled (explicitly or via experimentalHost), but respect numChannels if set
889937
dynamicChannelPoolEnabled = grpcGcpExtensionEnabled && !builder.numChannelsExplicitlySet;
890938
} else {
891939
// DCP is disabled by default, or was explicitly disabled
892940
dynamicChannelPoolEnabled = false;
893941
}
894942

895-
// Use user-provided GcpChannelPoolOptions or create Spanner-specific defaults
943+
// Use user-provided GcpChannelPoolOptions merged with Spanner-specific defaults,
944+
// or create Spanner-specific defaults if no custom options are provided.
945+
// This ensures that dynamic scaling parameters (minRpcPerChannel, maxRpcPerChannel,
946+
// scaleDownInterval) retain their defaults even when the user only customizes pool sizing.
896947
gcpChannelPoolOptions =
897948
builder.gcpChannelPoolOptions != null
898-
? builder.gcpChannelPoolOptions
949+
? mergeWithDefaultChannelPoolOptions(builder.gcpChannelPoolOptions)
899950
: createDefaultDynamicChannelPoolOptions();
900951

901952
autoThrottleAdministrativeRequests = builder.autoThrottleAdministrativeRequests;
@@ -930,7 +981,14 @@ protected SpannerOptions(Builder builder) {
930981
} else {
931982
enableBuiltInMetrics = builder.enableBuiltInMetrics;
932983
}
933-
enableLocationApi = builder.enableLocationApi;
984+
// Enable location API when experimental host is set, unless explicitly disabled
985+
// via GOOGLE_SPANNER_EXPERIMENTAL_LOCATION_API=false.
986+
if (builder.experimentalHost != null) {
987+
String locationApiEnvValue = System.getenv(EXPERIMENTAL_LOCATION_API_ENV_VAR);
988+
enableLocationApi = locationApiEnvValue == null || Boolean.parseBoolean(locationApiEnvValue);
989+
} else {
990+
enableLocationApi = builder.enableLocationApi;
991+
}
934992
enableEndToEndTracing = builder.enableEndToEndTracing;
935993
monitoringHost = builder.monitoringHost;
936994
defaultTransactionOptions = builder.defaultTransactionOptions;

0 commit comments

Comments
 (0)