Skip to content

Commit 6adf5b7

Browse files
feat(spanner): add EnableDirectAccess field to ClientConfig (#14287)
This change introduces the `EnableDirectAccess` boolean to `ClientConfig`, allowing users to explicitly configure whether the Spanner client connects to the directpath XDS endpoint. The environment variable `GOOGLE_SPANNER_ENABLE_DIRECT_ACCESS` continues to remain fully supported, and takes precedence over the programmatic client configuration for flexible overriding.
1 parent 3cd5716 commit 6adf5b7

1 file changed

Lines changed: 21 additions & 6 deletions

File tree

spanner/client.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ func createGCPMultiEndpoint(cfg *grpcgcp.GCPMultiEndpointOptions, config ClientC
234234
copts = append(copts, option.WithGRPCDialOption(do))
235235
}
236236

237-
allOpts := allClientOpts(1, config.Compression, copts...)
237+
allOpts := allClientOpts(1, config.Compression, config.EnableDirectAccess, copts...)
238238

239239
// Overwrite endpoint and pool config.
240240
allOpts = append(allOpts,
@@ -373,6 +373,13 @@ type ClientConfig struct {
373373

374374
// ClientContext is the default context for all requests made by the client.
375375
ClientContext *sppb.RequestOptions_ClientContext
376+
377+
// EnableDirectAccess option is used to enable the directpath.
378+
// This setting is overridden by the GOOGLE_SPANNER_ENABLE_DIRECT_ACCESS
379+
// environment variable if it is set.
380+
//
381+
// Default: false
382+
EnableDirectAccess bool
376383
}
377384

378385
type openTelemetryConfig struct {
@@ -494,7 +501,10 @@ func newClientWithConfig(ctx context.Context, database string, config ClientConf
494501
isAFEBuiltInMetricEnabled := strings.EqualFold("false", os.Getenv("SPANNER_DISABLE_AFE_SERVER_TIMING"))
495502
isGRPCBuiltInMetricsEnabled := strings.EqualFold("false", os.Getenv("SPANNER_DISABLE_DIRECT_ACCESS_GRPC_BUILTIN_METRICS"))
496503
// enable the AFE/GRPC built-in metrics if direct-path is enabled
497-
isDirectPathEnabled, _ := strconv.ParseBool(os.Getenv("GOOGLE_SPANNER_ENABLE_DIRECT_ACCESS"))
504+
isDirectPathEnabled := config.EnableDirectAccess
505+
if enableDirectPathXdsString := os.Getenv("GOOGLE_SPANNER_ENABLE_DIRECT_ACCESS"); enableDirectPathXdsString != "" {
506+
isDirectPathEnabled, _ = strconv.ParseBool(enableDirectPathXdsString)
507+
}
498508
if isDirectPathEnabled {
499509
isAFEBuiltInMetricEnabled = true
500510
isGRPCBuiltInMetricsEnabled = true
@@ -530,7 +540,7 @@ func newClientWithConfig(ctx context.Context, database string, config ClientConf
530540
option.WithGRPCDialOption(grpc.WithChainStreamInterceptor(reqIDInjector.interceptStream)),
531541
option.WithGRPCDialOption(grpc.WithChainUnaryInterceptor(reqIDInjector.interceptUnary)),
532542
)
533-
allOpts := allClientOpts(config.NumChannels, config.Compression, opts...)
543+
allOpts := allClientOpts(config.NumChannels, config.Compression, config.EnableDirectAccess, opts...)
534544
endpointClientOpts = append(endpointClientOpts, allOpts...)
535545
primaryConn, err = gtransport.DialPool(ctx, allOpts...)
536546
if err != nil {
@@ -575,7 +585,7 @@ func newClientWithConfig(ctx context.Context, database string, config ClientConf
575585
option.WithGRPCDialOption(grpc.WithChainUnaryInterceptor(reqIDInjector.interceptUnary)),
576586
)
577587

578-
allOpts := allClientOpts(config.NumChannels, config.Compression, opts...)
588+
allOpts := allClientOpts(config.NumChannels, config.Compression, config.EnableDirectAccess, opts...)
579589
endpointClientOpts = append(endpointClientOpts, allOpts...)
580590
pool, err = gtransport.DialPool(ctx, allOpts...)
581591
if err != nil {
@@ -752,7 +762,7 @@ func NewMultiEndpointClientWithConfig(ctx context.Context, database string, conf
752762
// Combines the default options from the generated client, the default options
753763
// of the hand-written client and the user options to one list of options.
754764
// Precedence: userOpts > clientDefaultOpts > generatedDefaultOpts
755-
func allClientOpts(numChannels int, compression string, userOpts ...option.ClientOption) []option.ClientOption {
765+
func allClientOpts(numChannels int, compression string, enableDirectAccess bool, userOpts ...option.ClientOption) []option.ClientOption {
756766
generatedDefaultOpts := vkit.DefaultClientOptions()
757767
clientDefaultOpts := []option.ClientOption{
758768
option.WithGRPCConnectionPool(numChannels),
@@ -761,7 +771,12 @@ func allClientOpts(numChannels int, compression string, userOpts ...option.Clien
761771
option.WithGRPCDialOption(grpc.WithChainStreamInterceptor(addStreamNativeMetricsInterceptor()...)),
762772
option.WithGRPCDialOption(grpc.WithKeepaliveParams(keepalive.ClientParameters{Time: 120 * time.Second})),
763773
}
764-
if enableDirectPathXds, _ := strconv.ParseBool(os.Getenv("GOOGLE_SPANNER_ENABLE_DIRECT_ACCESS")); enableDirectPathXds {
774+
enableDirectPathXds := enableDirectAccess
775+
if enableDirectPathXdsString := os.Getenv("GOOGLE_SPANNER_ENABLE_DIRECT_ACCESS"); enableDirectPathXdsString != "" {
776+
enableDirectPathXds, _ = strconv.ParseBool(enableDirectPathXdsString)
777+
}
778+
779+
if enableDirectPathXds {
765780
clientDefaultOpts = append(clientDefaultOpts, internaloption.AllowNonDefaultServiceAccount(true))
766781
clientDefaultOpts = append(clientDefaultOpts, internaloption.EnableDirectPath(true), internaloption.EnableDirectPathXds())
767782
if disableBoundToken, _ := strconv.ParseBool(os.Getenv("GOOGLE_SPANNER_DISABLE_DIRECT_ACCESS_BOUND_TOKEN")); !disableBoundToken {

0 commit comments

Comments
 (0)