Skip to content

Commit

Permalink
Move exponential backoff to DNS resolver from resolver.ClientConn (#4270
Browse files Browse the repository at this point in the history
)
  • Loading branch information
zasweq committed Apr 20, 2021
1 parent 41676e6 commit 1c598a1
Show file tree
Hide file tree
Showing 9 changed files with 301 additions and 280 deletions.
90 changes: 0 additions & 90 deletions balancer_conn_wrappers_test.go

This file was deleted.

17 changes: 1 addition & 16 deletions dialoptions.go
Expand Up @@ -66,11 +66,7 @@ type dialOptions struct {
minConnectTimeout func() time.Duration
defaultServiceConfig *ServiceConfig // defaultServiceConfig is parsed from defaultServiceConfigRawJSON.
defaultServiceConfigRawJSON *string
// This is used by ccResolverWrapper to backoff between successive calls to
// resolver.ResolveNow(). The user will have no need to configure this, but
// we need to be able to configure this in tests.
resolveNowBackoff func(int) time.Duration
resolvers []resolver.Builder
resolvers []resolver.Builder
}

// DialOption configures how we set up the connection.
Expand Down Expand Up @@ -596,7 +592,6 @@ func defaultDialOptions() dialOptions {
ReadBufferSize: defaultReadBufSize,
UseProxy: true,
},
resolveNowBackoff: internalbackoff.DefaultExponential.Backoff,
}
}

Expand All @@ -611,16 +606,6 @@ func withMinConnectDeadline(f func() time.Duration) DialOption {
})
}

// withResolveNowBackoff specifies the function that clientconn uses to backoff
// between successive calls to resolver.ResolveNow().
//
// For testing purpose only.
func withResolveNowBackoff(f func(int) time.Duration) DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.resolveNowBackoff = f
})
}

// WithResolvers allows a list of resolver implementations to be registered
// locally with the ClientConn without needing to be globally registered via
// resolver.Register. They will be matched against the scheme used for the
Expand Down
39 changes: 26 additions & 13 deletions internal/resolver/dns/dns_resolver.go
Expand Up @@ -34,6 +34,7 @@ import (

grpclbstate "google.golang.org/grpc/balancer/grpclb/state"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/backoff"
"google.golang.org/grpc/internal/envconfig"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/resolver"
Expand All @@ -46,6 +47,9 @@ var EnableSRVLookups = false

var logger = grpclog.Component("dns")

// A global to stub out in tests.
var newTimer = time.NewTimer

func init() {
resolver.Register(NewBuilder())
}
Expand Down Expand Up @@ -143,7 +147,6 @@ func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts

d.wg.Add(1)
go d.watcher()
d.ResolveNow(resolver.ResolveNowOptions{})
return d, nil
}

Expand Down Expand Up @@ -201,28 +204,38 @@ func (d *dnsResolver) Close() {

func (d *dnsResolver) watcher() {
defer d.wg.Done()
backoffIndex := 1
for {
select {
case <-d.ctx.Done():
return
case <-d.rn:
}

state, err := d.lookup()
if err != nil {
// Report error to the underlying grpc.ClientConn.
d.cc.ReportError(err)
} else {
d.cc.UpdateState(*state)
err = d.cc.UpdateState(*state)
}

// Sleep to prevent excessive re-resolutions. Incoming resolution requests
// will be queued in d.rn.
t := time.NewTimer(minDNSResRate)
var timer *time.Timer
if err == nil {
// Success resolving, wait for the next ResolveNow. However, also wait 30 seconds at the very least
// to prevent constantly re-resolving.
backoffIndex = 1
timer = time.NewTimer(minDNSResRate)
select {
case <-d.ctx.Done():
timer.Stop()
return
case <-d.rn:
}
} else {
// Poll on an error found in DNS Resolver or an error received from ClientConn.
timer = newTimer(backoff.DefaultExponential.Backoff(backoffIndex))
backoffIndex++
}
select {
case <-t.C:
case <-d.ctx.Done():
t.Stop()
timer.Stop()
return
case <-timer.C:
}
}
}
Expand Down

0 comments on commit 1c598a1

Please sign in to comment.