Skip to content

Commit 3cccf6a

Browse files
authored
xdsclient: always backoff between new streams even after successful stream (#5280)
1 parent 4e78093 commit 3cccf6a

File tree

7 files changed

+29
-35
lines changed

7 files changed

+29
-35
lines changed

xds/internal/xdsclient/authority.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func (c *clientImpl) newAuthority(config *bootstrap.ServerConfig) (_ *authority,
108108
ret.close()
109109
}
110110
}()
111-
ctr, err := newController(config, ret.pubsub, c.updateValidator, c.logger)
111+
ctr, err := newController(config, ret.pubsub, c.updateValidator, c.logger, nil)
112112
if err != nil {
113113
return nil, err
114114
}

xds/internal/xdsclient/client_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ type testController struct {
102102
func overrideNewController(t *testing.T) *testutils.Channel {
103103
origNewController := newController
104104
ch := testutils.NewChannel()
105-
newController = func(config *bootstrap.ServerConfig, pubsub *pubsub.Pubsub, validator xdsresource.UpdateValidatorFunc, logger *grpclog.PrefixLogger) (controllerInterface, error) {
105+
newController = func(config *bootstrap.ServerConfig, pubsub *pubsub.Pubsub, validator xdsresource.UpdateValidatorFunc, logger *grpclog.PrefixLogger, _ func(int) time.Duration) (controllerInterface, error) {
106106
ret := newTestController(config)
107107
ch.Send(ret)
108108
return ret, nil

xds/internal/xdsclient/controller.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
package xdsclient
1919

2020
import (
21+
"time"
22+
2123
"google.golang.org/grpc/internal/grpclog"
2224
"google.golang.org/grpc/xds/internal/xdsclient/bootstrap"
2325
"google.golang.org/grpc/xds/internal/xdsclient/controller"
@@ -33,6 +35,6 @@ type controllerInterface interface {
3335
Close()
3436
}
3537

36-
var newController = func(config *bootstrap.ServerConfig, pubsub *pubsub.Pubsub, validator xdsresource.UpdateValidatorFunc, logger *grpclog.PrefixLogger) (controllerInterface, error) {
37-
return controller.New(config, pubsub, validator, logger)
38+
var newController = func(config *bootstrap.ServerConfig, pubsub *pubsub.Pubsub, validator xdsresource.UpdateValidatorFunc, logger *grpclog.PrefixLogger, boff func(int) time.Duration) (controllerInterface, error) {
39+
return controller.New(config, pubsub, validator, logger, boff)
3840
}

xds/internal/xdsclient/controller/controller.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func SetGRPCDial(dialer func(target string, opts ...grpc.DialOption) (*grpc.Clie
100100
}
101101

102102
// New creates a new controller.
103-
func New(config *bootstrap.ServerConfig, updateHandler pubsub.UpdateHandler, validator xdsresource.UpdateValidatorFunc, logger *grpclog.PrefixLogger) (_ *Controller, retErr error) {
103+
func New(config *bootstrap.ServerConfig, updateHandler pubsub.UpdateHandler, validator xdsresource.UpdateValidatorFunc, logger *grpclog.PrefixLogger, boff func(int) time.Duration) (_ *Controller, retErr error) {
104104
switch {
105105
case config == nil:
106106
return nil, errors.New("xds: no xds_server provided")
@@ -120,12 +120,15 @@ func New(config *bootstrap.ServerConfig, updateHandler pubsub.UpdateHandler, val
120120
}),
121121
}
122122

123+
if boff == nil {
124+
boff = backoff.DefaultExponential.Backoff
125+
}
123126
ret := &Controller{
124127
config: config,
125128
updateValidator: validator,
126129
updateHandler: updateHandler,
127130

128-
backoff: backoff.DefaultExponential.Backoff, // TODO: should this be configurable?
131+
backoff: boff,
129132
streamCh: make(chan grpc.ClientStream, 1),
130133
sendCh: buffer.NewUnbounded(),
131134
watchMap: make(map[xdsresource.ResourceType]map[string]bool),

xds/internal/xdsclient/controller/controller_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func (s) TestNew(t *testing.T) {
9595

9696
for _, test := range tests {
9797
t.Run(test.name, func(t *testing.T) {
98-
c, err := New(test.config, noopUpdateHandler, nil, nil) // Only testing the config, other inputs are left as nil.
98+
c, err := New(test.config, noopUpdateHandler, nil, nil, nil) // Only testing the config, other inputs are left as nil.
9999
defer func() {
100100
if c != nil {
101101
c.Close()
@@ -123,7 +123,7 @@ func (s) TestNewWithGRPCDial(t *testing.T) {
123123

124124
// Set the dialer and make sure it is called.
125125
SetGRPCDial(customDialer)
126-
c, err := New(config, noopUpdateHandler, nil, nil)
126+
c, err := New(config, noopUpdateHandler, nil, nil, nil)
127127
if err != nil {
128128
t.Fatalf("New(%+v) = %v, want no error", config, err)
129129
}
@@ -138,7 +138,7 @@ func (s) TestNewWithGRPCDial(t *testing.T) {
138138

139139
// Reset the dialer and make sure it is not called.
140140
SetGRPCDial(grpc.Dial)
141-
c, err = New(config, noopUpdateHandler, nil, nil)
141+
c, err = New(config, noopUpdateHandler, nil, nil, nil)
142142
defer func() {
143143
if c != nil {
144144
c.Close()

xds/internal/xdsclient/controller/transport.go

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,26 +59,21 @@ func (t *Controller) run(ctx context.Context) {
5959
// report error (and log) when stats is transient failure.
6060

6161
retries := 0
62-
for {
63-
select {
64-
case <-ctx.Done():
65-
return
66-
default:
67-
}
68-
69-
if retries != 0 {
70-
timer := time.NewTimer(t.backoff(retries))
62+
lastStreamStartTime := time.Time{}
63+
for ctx.Err() == nil {
64+
dur := time.Until(lastStreamStartTime.Add(t.backoff(retries)))
65+
if dur > 0 {
66+
timer := time.NewTimer(dur)
7167
select {
7268
case <-timer.C:
7369
case <-ctx.Done():
74-
if !timer.Stop() {
75-
<-timer.C
76-
}
70+
timer.Stop()
7771
return
7872
}
7973
}
8074

8175
retries++
76+
lastStreamStartTime = time.Now()
8277
stream, err := t.vClient.NewStream(ctx, t.cc)
8378
if err != nil {
8479
t.updateHandler.NewConnectionError(err)
@@ -370,24 +365,21 @@ func (t *Controller) processAckInfo(ack *ackAction, stream grpc.ClientStream) (t
370365
// It blocks until the context is cancelled.
371366
func (t *Controller) reportLoad(ctx context.Context, cc *grpc.ClientConn, opts controllerversion.LoadReportingOptions) {
372367
retries := 0
373-
for {
374-
if ctx.Err() != nil {
375-
return
376-
}
377-
378-
if retries != 0 {
379-
timer := time.NewTimer(t.backoff(retries))
368+
lastStreamStartTime := time.Time{}
369+
for ctx.Err() == nil {
370+
dur := time.Until(lastStreamStartTime.Add(t.backoff(retries)))
371+
if dur > 0 {
372+
timer := time.NewTimer(dur)
380373
select {
381374
case <-timer.C:
382375
case <-ctx.Done():
383-
if !timer.Stop() {
384-
<-timer.C
385-
}
376+
timer.Stop()
386377
return
387378
}
388379
}
389380

390381
retries++
382+
lastStreamStartTime = time.Now()
391383
stream, err := t.vClient.NewLoadStatsStream(ctx, cc)
392384
if err != nil {
393385
t.logger.Warningf("lrs: failed to create stream: %v", err)

xds/internal/xdsclient/controller/v2_testutils_test.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -458,13 +458,10 @@ func newTestController(p pubsub.UpdateHandler, controlPlanAddr string, n *basepb
458458
Creds: grpc.WithTransportCredentials(insecure.NewCredentials()),
459459
TransportAPI: version.TransportV2,
460460
NodeProto: n,
461-
}, p, nil, l)
461+
}, p, nil, l, b)
462462
if err != nil {
463463
return nil, err
464464
}
465-
// This direct setting backoff seems a bit hacky, but should be OK for the
466-
// tests. Or we need to make it configurable in New().
467-
c.backoff = b
468465
return c, nil
469466
}
470467

0 commit comments

Comments
 (0)