Skip to content

Commit 620a118

Browse files
authored
xds/internal/balancer/clusterimpl: Switch cluster impl child to graceful switch (#6420)
1 parent 6b8f427 commit 620a118

File tree

1 file changed

+11
-40
lines changed

1 file changed

+11
-40
lines changed

xds/internal/balancer/clusterimpl/clusterimpl.go

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"google.golang.org/grpc/balancer"
3333
"google.golang.org/grpc/connectivity"
3434
"google.golang.org/grpc/internal"
35+
"google.golang.org/grpc/internal/balancer/gracefulswitch"
3536
"google.golang.org/grpc/internal/buffer"
3637
"google.golang.org/grpc/internal/grpclog"
3738
"google.golang.org/grpc/internal/grpcsync"
@@ -69,6 +70,7 @@ func (bb) Build(cc balancer.ClientConn, bOpts balancer.BuildOptions) balancer.Ba
6970
requestCountMax: defaultRequestCountMax,
7071
}
7172
b.logger = prefixLogger(b)
73+
b.child = gracefulswitch.NewBalancer(b, bOpts)
7274
go b.run()
7375
b.logger.Infof("Created")
7476
return b
@@ -102,7 +104,7 @@ type clusterImplBalancer struct {
102104
xdsClient xdsclient.XDSClient
103105

104106
config *LBConfig
105-
childLB balancer.Balancer
107+
child *gracefulswitch.Balancer
106108
cancelLoadReport func()
107109
edsServiceName string
108110
lrsServer *bootstrap.ServerConfig
@@ -251,31 +253,19 @@ func (b *clusterImplBalancer) UpdateClientConnState(s balancer.ClientConnState)
251253
return err
252254
}
253255

254-
// If child policy is a different type, recreate the sub-balancer.
255256
if b.config == nil || b.config.ChildPolicy.Name != newConfig.ChildPolicy.Name {
256-
if b.childLB != nil {
257-
b.childLB.Close()
257+
if err := b.child.SwitchTo(bb); err != nil {
258+
return fmt.Errorf("error switching to child of type %q: %v", newConfig.ChildPolicy.Name, err)
258259
}
259-
b.childLB = bb.Build(b, b.bOpts)
260260
}
261261
b.config = newConfig
262262

263-
if b.childLB == nil {
264-
// This is not an expected situation, and should be super rare in
265-
// practice.
266-
//
267-
// When this happens, we already applied all the other configurations
268-
// (drop/circuit breaking), but there's no child policy. This balancer
269-
// will be stuck, and we report the error to the parent.
270-
return fmt.Errorf("child policy is nil, this means balancer %q's Build() returned nil", newConfig.ChildPolicy.Name)
271-
}
272-
273263
// Notify run() of this new config, in case drop and request counter need
274264
// update (which means a new picker needs to be generated).
275265
b.pickerUpdateCh.Put(newConfig)
276266

277267
// Addresses and sub-balancer config are sent to sub-balancer.
278-
return b.childLB.UpdateClientConnState(balancer.ClientConnState{
268+
return b.child.UpdateClientConnState(balancer.ClientConnState{
279269
ResolverState: s.ResolverState,
280270
BalancerConfig: b.config.ChildPolicy.Config,
281271
})
@@ -286,10 +276,7 @@ func (b *clusterImplBalancer) ResolverError(err error) {
286276
b.logger.Warningf("xds: received resolver error {%+v} after clusterImplBalancer was closed", err)
287277
return
288278
}
289-
290-
if b.childLB != nil {
291-
b.childLB.ResolverError(err)
292-
}
279+
b.child.ResolverError(err)
293280
}
294281

295282
func (b *clusterImplBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer.SubConnState) {
@@ -318,39 +305,23 @@ func (b *clusterImplBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer
318305
}
319306
}
320307
b.scWrappersMu.Unlock()
321-
if b.childLB != nil {
322-
b.childLB.UpdateSubConnState(sc, s)
323-
}
308+
b.child.UpdateSubConnState(sc, s)
324309
}
325310

326311
func (b *clusterImplBalancer) Close() {
327312
b.mu.Lock()
328313
b.closed.Fire()
329314
b.mu.Unlock()
330315

331-
if b.childLB != nil {
332-
b.childLB.Close()
333-
b.childLB = nil
334-
b.childState = balancer.State{}
335-
}
316+
b.child.Close()
317+
b.childState = balancer.State{}
336318
b.pickerUpdateCh.Close()
337319
<-b.done.Done()
338320
b.logger.Infof("Shutdown")
339321
}
340322

341323
func (b *clusterImplBalancer) ExitIdle() {
342-
if b.childLB == nil {
343-
return
344-
}
345-
if ei, ok := b.childLB.(balancer.ExitIdler); ok {
346-
ei.ExitIdle()
347-
return
348-
}
349-
// Fallback for children that don't support ExitIdle -- connect to all
350-
// SubConns.
351-
for _, sc := range b.scWrappers {
352-
sc.Connect()
353-
}
324+
b.child.ExitIdle()
354325
}
355326

356327
// Override methods to accept updates from the child LB.

0 commit comments

Comments
 (0)