client: introduce WithDisableServiceConfig DialOption (#2010)
This commit is contained in:
@ -108,9 +108,10 @@ type dialOptions struct {
|
|||||||
// balancer, and also by WithBalancerName dial option.
|
// balancer, and also by WithBalancerName dial option.
|
||||||
balancerBuilder balancer.Builder
|
balancerBuilder balancer.Builder
|
||||||
// This is to support grpclb.
|
// This is to support grpclb.
|
||||||
resolverBuilder resolver.Builder
|
resolverBuilder resolver.Builder
|
||||||
waitForHandshake bool
|
waitForHandshake bool
|
||||||
channelzParentID int64
|
channelzParentID int64
|
||||||
|
disableServiceConfig bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -416,6 +417,15 @@ func WithChannelzParentID(id int64) DialOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithDisableServiceConfig returns a DialOption that causes grpc to ignore any
|
||||||
|
// service config provided by the resolver and provides a hint to the resolver
|
||||||
|
// to not fetch service configs.
|
||||||
|
func WithDisableServiceConfig() DialOption {
|
||||||
|
return func(o *dialOptions) {
|
||||||
|
o.disableServiceConfig = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Dial creates a client connection to the given target.
|
// Dial creates a client connection to the given target.
|
||||||
func Dial(target string, opts ...DialOption) (*ClientConn, error) {
|
func Dial(target string, opts ...DialOption) (*ClientConn, error) {
|
||||||
return DialContext(context.Background(), target, opts...)
|
return DialContext(context.Background(), target, opts...)
|
||||||
@ -1002,6 +1012,9 @@ func (cc *ClientConn) getTransport(ctx context.Context, failfast bool) (transpor
|
|||||||
// handleServiceConfig parses the service config string in JSON format to Go native
|
// handleServiceConfig parses the service config string in JSON format to Go native
|
||||||
// struct ServiceConfig, and store both the struct and the JSON string in ClientConn.
|
// struct ServiceConfig, and store both the struct and the JSON string in ClientConn.
|
||||||
func (cc *ClientConn) handleServiceConfig(js string) error {
|
func (cc *ClientConn) handleServiceConfig(js string) error {
|
||||||
|
if cc.dopts.disableServiceConfig {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
sc, err := parseServiceConfig(js)
|
sc, err := parseServiceConfig(js)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -646,3 +646,32 @@ func TestClientUpdatesParamsAfterGoAway(t *testing.T) {
|
|||||||
t.Fatalf("cc.dopts.copts.Keepalive.Time = %v , want 100ms", v)
|
t.Fatalf("cc.dopts.copts.Keepalive.Time = %v , want 100ms", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDisableServiceConfigOption(t *testing.T) {
|
||||||
|
r, cleanup := manual.GenerateAndRegisterManualResolver()
|
||||||
|
defer cleanup()
|
||||||
|
addr := r.Scheme() + ":///non.existent"
|
||||||
|
cc, err := Dial(addr, WithInsecure(), WithDisableServiceConfig())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Dial(%s, _) = _, %v, want _, <nil>", addr, err)
|
||||||
|
}
|
||||||
|
defer cc.Close()
|
||||||
|
r.NewServiceConfig(`{
|
||||||
|
"methodConfig": [
|
||||||
|
{
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"service": "foo",
|
||||||
|
"method": "Bar"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"waitForReady": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`)
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
m := cc.GetMethodConfig("/foo/Bar")
|
||||||
|
if m.WaitForReady != nil {
|
||||||
|
t.Fatalf("want: method (\"/foo/bar/\") config to be empty, got: %v", m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -90,14 +90,15 @@ func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts
|
|||||||
// DNS address (non-IP).
|
// DNS address (non-IP).
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
d := &dnsResolver{
|
d := &dnsResolver{
|
||||||
freq: b.freq,
|
freq: b.freq,
|
||||||
host: host,
|
host: host,
|
||||||
port: port,
|
port: port,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
cc: cc,
|
cc: cc,
|
||||||
t: time.NewTimer(0),
|
t: time.NewTimer(0),
|
||||||
rn: make(chan struct{}, 1),
|
rn: make(chan struct{}, 1),
|
||||||
|
disableServiceConfig: opts.DisableServiceConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
d.wg.Add(1)
|
d.wg.Add(1)
|
||||||
@ -160,7 +161,8 @@ type dnsResolver struct {
|
|||||||
// If Close() doesn't wait for watcher() goroutine finishes, race detector sometimes
|
// If Close() doesn't wait for watcher() goroutine finishes, race detector sometimes
|
||||||
// will warns lookup (READ the lookup function pointers) inside watcher() goroutine
|
// will warns lookup (READ the lookup function pointers) inside watcher() goroutine
|
||||||
// has data race with replaceNetFunc (WRITE the lookup function pointers).
|
// has data race with replaceNetFunc (WRITE the lookup function pointers).
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
disableServiceConfig bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveNow invoke an immediate resolution of the target that this dnsResolver watches.
|
// ResolveNow invoke an immediate resolution of the target that this dnsResolver watches.
|
||||||
@ -205,7 +207,7 @@ func (d *dnsResolver) lookupSRV() []resolver.Address {
|
|||||||
for _, s := range srvs {
|
for _, s := range srvs {
|
||||||
lbAddrs, err := lookupHost(d.ctx, s.Target)
|
lbAddrs, err := lookupHost(d.ctx, s.Target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
grpclog.Warningf("grpc: failed load balancer address dns lookup due to %v.\n", err)
|
grpclog.Infof("grpc: failed load balancer address dns lookup due to %v.\n", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, a := range lbAddrs {
|
for _, a := range lbAddrs {
|
||||||
@ -224,7 +226,7 @@ func (d *dnsResolver) lookupSRV() []resolver.Address {
|
|||||||
func (d *dnsResolver) lookupTXT() string {
|
func (d *dnsResolver) lookupTXT() string {
|
||||||
ss, err := lookupTXT(d.ctx, d.host)
|
ss, err := lookupTXT(d.ctx, d.host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
grpclog.Warningf("grpc: failed dns TXT record lookup due to %v.\n", err)
|
grpclog.Infof("grpc: failed dns TXT record lookup due to %v.\n", err)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
var res string
|
var res string
|
||||||
@ -263,6 +265,9 @@ func (d *dnsResolver) lookup() ([]resolver.Address, string) {
|
|||||||
newAddrs := d.lookupSRV()
|
newAddrs := d.lookupSRV()
|
||||||
// Support fallback to non-balancer address.
|
// Support fallback to non-balancer address.
|
||||||
newAddrs = append(newAddrs, d.lookupHost()...)
|
newAddrs = append(newAddrs, d.lookupHost()...)
|
||||||
|
if d.disableServiceConfig {
|
||||||
|
return newAddrs, ""
|
||||||
|
}
|
||||||
sc := d.lookupTXT()
|
sc := d.lookupTXT()
|
||||||
return newAddrs, canaryingSC(sc)
|
return newAddrs, canaryingSC(sc)
|
||||||
}
|
}
|
||||||
|
@ -892,3 +892,45 @@ func TestResolveFunc(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDisableServiceConfig(t *testing.T) {
|
||||||
|
defer leakcheck.Check(t)
|
||||||
|
tests := []struct {
|
||||||
|
target string
|
||||||
|
scWant string
|
||||||
|
disableServiceConfig bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"foo.bar.com",
|
||||||
|
generateSC("foo.bar.com"),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"foo.bar.com",
|
||||||
|
"",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range tests {
|
||||||
|
b := NewBuilder()
|
||||||
|
cc := &testClientConn{target: a.target}
|
||||||
|
r, err := b.Build(resolver.Target{Endpoint: a.target}, cc, resolver.BuildOption{DisableServiceConfig: a.disableServiceConfig})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%v\n", err)
|
||||||
|
}
|
||||||
|
var cnt int
|
||||||
|
var sc string
|
||||||
|
for {
|
||||||
|
sc, cnt = cc.getSc()
|
||||||
|
if cnt > 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(a.scWant, sc) {
|
||||||
|
t.Errorf("Resolved service config of target: %q = %+v, want %+v\n", a.target, sc, a.scWant)
|
||||||
|
}
|
||||||
|
r.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -90,6 +90,8 @@ type Address struct {
|
|||||||
// BuildOption includes additional information for the builder to create
|
// BuildOption includes additional information for the builder to create
|
||||||
// the resolver.
|
// the resolver.
|
||||||
type BuildOption struct {
|
type BuildOption struct {
|
||||||
|
// DisableServiceConfig indicates whether resolver should fetch service config data.
|
||||||
|
DisableServiceConfig bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientConn contains the callbacks for resolver to notify any updates
|
// ClientConn contains the callbacks for resolver to notify any updates
|
||||||
|
@ -84,7 +84,7 @@ func newCCResolverWrapper(cc *ClientConn) (*ccResolverWrapper, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
ccr.resolver, err = rb.Build(cc.parsedTarget, ccr, resolver.BuildOption{})
|
ccr.resolver, err = rb.Build(cc.parsedTarget, ccr, resolver.BuildOption{DisableServiceConfig: cc.dopts.disableServiceConfig})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user