Skip to content

Commit

Permalink
Add LateApplyDialOption and global list
Browse files Browse the repository at this point in the history
  • Loading branch information
zasweq committed May 14, 2024
1 parent 59954c8 commit e90323f
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 14 deletions.
33 changes: 19 additions & 14 deletions clientconn.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,25 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error)
for _, opt := range opts {
opt.apply(&cc.dopts)
}

// Register ClientConn with channelz.
cc.channelzRegistration(target)
// TODO: Ideally it should be impossible to error from this function after
// channelz registration. This will require removing some channelz logs
// from the following functions that can error. Errors can be returned to
// the user, and successful logs can be emitted here, after the checks have
// passed and channelz is subsequently registered.

// Determine the resolver to use.
if err := cc.parseTargetAndFindResolver(); err != nil {
channelz.RemoveEntry(cc.channelz.ID)
return nil, err
}

for _, lateApplyOpt := range globalLateApplyDialOptions {
lateApplyOpt.DialOption(cc.parsedTarget.URL).apply(&cc.dopts)
}

chainUnaryClientInterceptors(cc)
chainStreamClientInterceptors(cc)

Expand All @@ -168,20 +187,6 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error)
}
cc.mkp = cc.dopts.copts.KeepaliveParams

// Register ClientConn with channelz.
cc.channelzRegistration(target)

// TODO: Ideally it should be impossible to error from this function after
// channelz registration. This will require removing some channelz logs
// from the following functions that can error. Errors can be returned to
// the user, and successful logs can be emitted here, after the checks have
// passed and channelz is subsequently registered.

// Determine the resolver to use.
if err := cc.parseTargetAndFindResolver(); err != nil {
channelz.RemoveEntry(cc.channelz.ID)
return nil, err
}
if err = cc.determineAuthority(); err != nil {
channelz.RemoveEntry(cc.channelz.ID)
return nil, err
Expand Down
25 changes: 25 additions & 0 deletions default_dial_option_server_option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package grpc

import (
"fmt"
"net/url"
"strings"
"testing"

Expand Down Expand Up @@ -74,6 +75,30 @@ func (s) TestDisableGlobalOptions(t *testing.T) {
internal.ClearGlobalDialOptions()
}

type testLateApplyDialOption struct{}

func (do *testLateApplyDialOption) DialOption(parsedTarget url.URL) DialOption {
print("parsedTarget.Scheme: ", parsedTarget.Scheme)
if parsedTarget.Scheme == "passthrough" {
return WithTransportCredentials(insecure.NewCredentials()) // credentials provided, should pass NewClient.
}
return WithReadBufferSize(10) // no credentials, should fail NewClient
}

func (s) TestGlobalLateApplyDialOption(t *testing.T) {
internal.AddGlobalLateApplyDialOptions.(func(opt ...LateApplyDialOption))(&testLateApplyDialOption{}) // Do I need a clear?
noTSecStr := "no transport security set"
if _, err := NewClient("fake"); !strings.Contains(fmt.Sprint(err), noTSecStr) {
t.Fatalf("Dialing received unexpected error: %v, want error containing \"%v\"", err, noTSecStr)
}
cc, err := NewClient("passthrough:///nice")
if err != nil {
t.Fatalf("Dialing with insecure credentials failed: %v", err)
}
defer cc.Close()
internal.ClearGlobalLateApplyDialOptions()
}

func (s) TestAddGlobalServerOptions(t *testing.T) {
const maxRecvSize = 998765
// Set and check the ServerOptions
Expand Down
15 changes: 15 additions & 0 deletions dialoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package grpc
import (
"context"
"net"
"net/url"
"time"

"google.golang.org/grpc/backoff"
Expand All @@ -43,6 +44,12 @@ func init() {
internal.ClearGlobalDialOptions = func() {
globalDialOptions = nil
}
internal.AddGlobalLateApplyDialOptions = func(opt ...LateApplyDialOption) {
globalLateApplyDialOptions = append(globalLateApplyDialOptions, opt...)
}
internal.ClearGlobalLateApplyDialOptions = func() {
globalLateApplyDialOptions = nil
}
internal.WithBinaryLogger = withBinaryLogger
internal.JoinDialOptions = newJoinDialOption
internal.DisableGlobalDialOptions = newDisableGlobalDialOptions
Expand Down Expand Up @@ -89,6 +96,14 @@ type DialOption interface {

var globalDialOptions []DialOption

// LateApplyDialOption takes a parsed target and returns a dial option to apply.
type LateApplyDialOption interface {
// DialOption returns a Dial Option to apply.
DialOption(parsedTarget url.URL) DialOption
}

var globalLateApplyDialOptions []LateApplyDialOption

// EmptyDialOption does not alter the dial configuration. It can be embedded in
// another structure to build custom dial options.
//
Expand Down
8 changes: 8 additions & 0 deletions internal/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ var (
// This is used in the 1.0 release of gcp/observability, and thus must not be
// deleted or changed.
ClearGlobalDialOptions func()

// AddGlobalLateApplyDialOptions adds a slice of lateApplyDialOptions that
// will be configured for newly created ClientConns.
AddGlobalLateApplyDialOptions any // func (opt ...lateApplyDialOption)
// ClearGlobalLateApplyDialOptions clears the slice of global late apply
// dial options.
ClearGlobalLateApplyDialOptions func()

// JoinDialOptions combines the dial options passed as arguments into a
// single dial option.
JoinDialOptions any // func(...grpc.DialOption) grpc.DialOption
Expand Down

0 comments on commit e90323f

Please sign in to comment.