| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -281,6 +281,7 @@ public class GapicSpannerRpc implements SpannerRpc { | |
| private final boolean endToEndTracingEnabled; | ||
| private final int numChannels; | ||
| private final boolean isGrpcGcpExtensionEnabled; | ||
| private final boolean isDynamicChannelPoolEnabled; | ||
|
|
||
| private final GrpcCallContext baseGrpcCallContext; | ||
|
|
||
| Expand Down Expand Up | @@ -337,6 +338,7 @@ public GapicSpannerRpc(final SpannerOptions options) { | |
| this.endToEndTracingEnabled = options.isEndToEndTracingEnabled(); | ||
| this.numChannels = options.getNumChannels(); | ||
| this.isGrpcGcpExtensionEnabled = options.isGrpcGcpExtensionEnabled(); | ||
| this.isDynamicChannelPoolEnabled = options.isDynamicChannelPoolEnabled(); | ||
| this.baseGrpcCallContext = createBaseCallContext(); | ||
|
|
||
| if (initializeStubs) { | ||
| Expand Down Expand Up | @@ -475,7 +477,8 @@ public GapicSpannerRpc(final SpannerOptions options) { | |
| .withCheckInterval(pdmlSettings.getStreamWatchdogCheckInterval())); | ||
| } | ||
| this.partitionedDmlStub = | ||
| GrpcSpannerStubWithStubSettingsAndClientContext.create(pdmlSettings.build()); | ||
| GrpcSpannerStubWithStubSettingsAndClientContext.create( | ||
| pdmlSettings.build(), clientContext); | ||
| this.instanceAdminStubSettings = | ||
| options.getInstanceAdminStubSettings().toBuilder() | ||
| .setTransportChannelProvider(channelProvider) | ||
| Expand Down Expand Up | @@ -569,10 +572,14 @@ private static String parseGrpcGcpApiConfig() { | |
| } | ||
| } | ||
|
|
||
| // Enhance metric options for gRPC-GCP extension. | ||
| private static GcpManagedChannelOptions grpcGcpOptionsWithMetrics(SpannerOptions options) { | ||
| // Enhance gRPC-GCP options with metrics and dynamic channel pool configuration. | ||
| private static GcpManagedChannelOptions grpcGcpOptionsWithMetricsAndDcp(SpannerOptions options) { | ||
| GcpManagedChannelOptions grpcGcpOptions = | ||
| MoreObjects.firstNonNull(options.getGrpcGcpOptions(), new GcpManagedChannelOptions()); | ||
| GcpManagedChannelOptions.Builder optionsBuilder = | ||
| GcpManagedChannelOptions.newBuilder(grpcGcpOptions); | ||
|
|
||
| // Configure metrics options with OpenTelemetry meter | ||
| GcpMetricsOptions metricsOptions = | ||
| MoreObjects.firstNonNull( | ||
| grpcGcpOptions.getMetricsOptions(), GcpMetricsOptions.newBuilder().build()); | ||
| Expand All | @@ -581,9 +588,21 @@ private static GcpManagedChannelOptions grpcGcpOptionsWithMetrics(SpannerOptions | |
| if (metricsOptions.getNamePrefix().equals("")) { | ||
| metricsOptionsBuilder.withNamePrefix("cloud.google.com/java/spanner/gcp-channel-pool/"); | ||
| } | ||
| return GcpManagedChannelOptions.newBuilder(grpcGcpOptions) | ||
| .withMetricsOptions(metricsOptionsBuilder.build()) | ||
| .build(); | ||
| // Pass OpenTelemetry meter to grpc-gcp for channel pool metrics | ||
| if (metricsOptions.getOpenTelemetryMeter() == null) { | ||
| metricsOptionsBuilder.withOpenTelemetryMeter( | ||
| options.getOpenTelemetry().getMeter("com.google.cloud.spanner")); | ||
| } | ||
| optionsBuilder.withMetricsOptions(metricsOptionsBuilder.build()); | ||
|
|
||
| // Configure dynamic channel pool options if enabled. | ||
| // Uses the GcpChannelPoolOptions from SpannerOptions, which contains Spanner-specific defaults | ||
| // or user-provided configuration. | ||
| if (options.isDynamicChannelPoolEnabled()) { | ||
| optionsBuilder.withChannelPoolOptions(options.getGcpChannelPoolOptions()); | ||
| } | ||
|
|
||
| return optionsBuilder.build(); | ||
| } | ||
|
|
||
| @SuppressWarnings("rawtypes") | ||
| Expand All | @@ -595,7 +614,11 @@ private static void maybeEnableGrpcGcpExtension( | |
| } | ||
|
|
||
| final String jsonApiConfig = parseGrpcGcpApiConfig(); | ||
| final GcpManagedChannelOptions grpcGcpOptions = grpcGcpOptionsWithMetrics(options); | ||
| final GcpManagedChannelOptions grpcGcpOptions = grpcGcpOptionsWithMetricsAndDcp(options); | ||
|
|
||
| // 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(); | ||
|
Comment thread
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityDoes 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)
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityNo, 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.
Sorry, something went wrong.
All reactions
|
||
|
|
||
| ApiFunction<ManagedChannelBuilder, ManagedChannelBuilder> apiFunction = | ||
| channelBuilder -> { | ||
| Expand All | @@ -605,7 +628,7 @@ private static void maybeEnableGrpcGcpExtension( | |
| return GcpManagedChannelBuilder.forDelegateBuilder(channelBuilder) | ||
| .withApiConfigJsonString(jsonApiConfig) | ||
| .withOptions(grpcGcpOptions) | ||
| .setPoolSize(options.getNumChannels()); | ||
| .setPoolSize(poolSize); | ||
| }; | ||
|
|
||
| // Disable the GAX channel pooling functionality by setting the GAX channel pool size to 1. | ||
| Expand Down Expand Up | @@ -2060,20 +2083,34 @@ <ReqT, RespT> GrpcCallContext newCallContext( | |
| if (affinity != null) { | ||
| if (this.isGrpcGcpExtensionEnabled) { | ||
| // Set channel affinity in gRPC-GCP. | ||
| // Compute bounded channel hint to prevent gRPC-GCP affinity map from getting unbounded. | ||
| int boundedChannelHint = affinity.intValue() % this.numChannels; | ||
| String affinityKey; | ||
| if (this.isDynamicChannelPoolEnabled) { | ||
| // When dynamic channel pooling is enabled, we use the raw affinity value as the key. | ||
| // This allows grpc-gcp to use round-robin for new keys, enabling new channels | ||
| // (created during scale-up) to receive requests. The affinity key lifetime setting | ||
| // ensures the affinity map doesn't grow unbounded. | ||
| affinityKey = String.valueOf(affinity); | ||
| } else { | ||
| // When DCP is disabled, compute bounded channel hint to prevent | ||
| // gRPC-GCP affinity map from getting unbounded. | ||
| int boundedChannelHint = affinity.intValue() % this.numChannels; | ||
| affinityKey = String.valueOf(boundedChannelHint); | ||
| } | ||
| context = | ||
| context.withCallOptions( | ||
| context | ||
| .getCallOptions() | ||
| .withOption( | ||
| GcpManagedChannel.AFFINITY_KEY, String.valueOf(boundedChannelHint))); | ||
| context.getCallOptions().withOption(GcpManagedChannel.AFFINITY_KEY, affinityKey)); | ||
| } else { | ||
| // Set channel affinity in GAX. | ||
| context = context.withChannelAffinity(affinity.intValue()); | ||
| } | ||
| } | ||
| int requestIdChannel = convertToRequestIdChannelNumber(affinity); | ||
| // When grpc-gcp extension with dynamic channel pooling is enabled, the actual channel ID | ||
| // will be set by RequestIdInterceptor after grpc-gcp selects the channel. | ||
| // Set to 0 (unknown) here as a placeholder. | ||
| int requestIdChannel = | ||
| (this.isGrpcGcpExtensionEnabled && this.isDynamicChannelPoolEnabled) | ||
| ? 0 | ||
| : convertToRequestIdChannelNumber(affinity); | ||
| if (requestId == null) { | ||
| requestId = requestIdCreator.nextRequestId(requestIdChannel); | ||
| } else { | ||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.