Skip to content

Commit

Permalink
feat(option): add AttemptDirectPath option
Browse files Browse the repository at this point in the history
  • Loading branch information
mohanli-ml committed Oct 30, 2020
1 parent 5b35910 commit 1a5b734
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 15 deletions.
1 change: 1 addition & 0 deletions internal/settings.go
Expand Up @@ -41,6 +41,7 @@ type DialSettings struct {
CustomClaims map[string]interface{}
SkipValidation bool
ImpersonationConfig *impersonate.Config
AttemptDirectPath bool

// Google API system parameters. For more information please read:
// https://cloud.google.com/apis/docs/system-parameters
Expand Down
12 changes: 12 additions & 0 deletions option/option.go
Expand Up @@ -324,3 +324,15 @@ func (i impersonateServiceAccount) Apply(o *internal.DialSettings) {
o.ImpersonationConfig.Delegates = make([]string, len(i.delegates))
copy(o.ImpersonationConfig.Delegates, i.delegates)
}

// WithAttemptDirectPath returns a ClientOption that overrides the default
// attempt to use DirectPath
func WithAttemptDirectPath(dp bool) ClientOption {
return withAttemptDirectPath(dp)
}

type withAttemptDirectPath bool

func (w withAttemptDirectPath) Apply(o *internal.DialSettings) {
o.AttemptDirectPath = bool(w)
}
20 changes: 5 additions & 15 deletions transport/grpc/dial.go
Expand Up @@ -12,7 +12,6 @@ import (
"crypto/tls"
"errors"
"log"
"os"
"strings"

"go.opencensus.io/plugin/ocgrpc"
Expand Down Expand Up @@ -135,12 +134,11 @@ func dial(ctx context.Context, insecure bool, o *internal.DialSettings) (*grpc.C
}

// Attempt Direct Path only if:
// * Yoshi library set AttemptDirectPath option
// * The endpoint is a host:port (or dns:///host:port).
// * Credentials are obtained via GCE metadata server, using the default
// service account.
// * Opted in via GOOGLE_CLOUD_ENABLE_DIRECT_PATH environment variable.
// For example, GOOGLE_CLOUD_ENABLE_DIRECT_PATH=spanner,pubsub
if isDirectPathEnabled(endpoint) && isTokenSourceDirectPathCompatible(creds.TokenSource) {
if o.AttemptDirectPath && checkDirectPathEndPoint(endpoint) && isTokenSourceDirectPathCompatible(creds.TokenSource) {
if !strings.HasPrefix(endpoint, "dns:///") {
endpoint = "dns:///" + endpoint
}
Expand Down Expand Up @@ -189,7 +187,7 @@ func dial(ctx context.Context, insecure bool, o *internal.DialSettings) (*grpc.C
// point when isDirectPathEnabled will default to true, we guard it by
// the Directpath env var for now once we can introspect user defined
// dialer (https://github.com/grpc/grpc-go/issues/2795).
if timeoutDialerOption != nil && isDirectPathEnabled(endpoint) {
if timeoutDialerOption != nil && o.AttemptDirectPath && checkDirectPathEndPoint(endpoint) {
grpcOpts = append(grpcOpts, timeoutDialerOption)
}

Expand Down Expand Up @@ -250,7 +248,7 @@ func isTokenSourceDirectPathCompatible(ts oauth2.TokenSource) bool {
return true
}

func isDirectPathEnabled(endpoint string) bool {
func checkDirectPathEndPoint(endpoint string) bool {
// Only host:port is supported, not other schemes (e.g., "tcp://" or "unix://").
// Also don't try direct path if the user has chosen an alternate name resolver
// (i.e., via ":///" prefix).
Expand All @@ -261,15 +259,7 @@ func isDirectPathEnabled(endpoint string) bool {
return false
}

// Only try direct path if the user has opted in via the environment variable.
directPathAPIs := strings.Split(os.Getenv("GOOGLE_CLOUD_ENABLE_DIRECT_PATH"), ",")
for _, api := range directPathAPIs {
// Ignore empty string since an empty env variable splits into [""]
if api != "" && strings.Contains(endpoint, api) {
return true
}
}
return false
return true
}

func processAndValidateOpts(opts []option.ClientOption) (*internal.DialSettings, error) {
Expand Down

0 comments on commit 1a5b734

Please sign in to comment.