Skip to content

Commit dbd5915

Browse files
committed
Add ExitIdle to the Balancer interface
1 parent 98ebf34 commit dbd5915

File tree

24 files changed

+59
-114
lines changed

24 files changed

+59
-114
lines changed

balancer/balancer.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,15 +360,19 @@ type Balancer interface {
360360
// call SubConn.Shutdown for its existing SubConns; however, this will be
361361
// required in a future release, so it is recommended.
362362
Close()
363+
// ExitIdle instructs the LB policy to reconnect to backends / exit the
364+
// IDLE state, if appropriate and possible. Note that SubConns that enter
365+
// the IDLE state will not reconnect until SubConn.Connect is called.
366+
ExitIdle()
363367
}
364368

365369
// ExitIdler is an optional interface for balancers to implement. If
366370
// implemented, ExitIdle will be called when ClientConn.Connect is called, if
367371
// the ClientConn is idle. If unimplemented, ClientConn.Connect will cause
368372
// all SubConns to connect.
369373
//
370-
// Notice: it will be required for all balancers to implement this in a future
371-
// release.
374+
// Deprecated: All balancers must implement this interface. This interface will
375+
// be removed in a future release.
372376
type ExitIdler interface {
373377
// ExitIdle instructs the LB policy to reconnect to backends / exit the
374378
// IDLE state, if appropriate and possible. Note that SubConns that enter

balancer/endpointsharding/endpointsharding.go

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,16 @@ package endpointsharding
2727

2828
import (
2929
"errors"
30-
"fmt"
3130
rand "math/rand/v2"
3231
"sync"
3332
"sync/atomic"
3433

3534
"google.golang.org/grpc/balancer"
3635
"google.golang.org/grpc/balancer/base"
3736
"google.golang.org/grpc/connectivity"
38-
"google.golang.org/grpc/grpclog"
39-
internalgrpclog "google.golang.org/grpc/internal/grpclog"
4037
"google.golang.org/grpc/resolver"
4138
)
4239

43-
var logger = grpclog.Component("endpointsharding-lb")
44-
4540
// ChildState is the balancer state of a child along with the endpoint which
4641
// identifies the child balancer.
4742
type ChildState struct {
@@ -50,7 +45,15 @@ type ChildState struct {
5045

5146
// Balancer exposes only the ExitIdler interface of the child LB policy.
5247
// Other methods of the child policy are called only by endpointsharding.
53-
Balancer balancer.ExitIdler
48+
Balancer ExitIdler
49+
}
50+
51+
// ExitIdler provides access to only the ExitIdle method of the child balancer.
52+
type ExitIdler interface {
53+
// ExitIdle instructs the LB policy to reconnect to backends / exit the
54+
// IDLE state, if appropriate and possible. Note that SubConns that enter
55+
// the IDLE state will not reconnect until SubConn.Connect is called.
56+
ExitIdle()
5457
}
5558

5659
// Options are the options to configure the behaviour of the
@@ -78,7 +81,6 @@ func NewBalancer(cc balancer.ClientConn, opts balancer.BuildOptions, childBuilde
7881
esOpts: esOpts,
7982
childBuilder: childBuilder,
8083
}
81-
es.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[endpointsharding-lb %p] ", es))
8284
es.children.Store(resolver.NewEndpointMap[*balancerWrapper]())
8385
return es
8486
}
@@ -91,7 +93,6 @@ type endpointSharding struct {
9193
bOpts balancer.BuildOptions
9294
esOpts Options
9395
childBuilder ChildBuilderFunc
94-
logger *internalgrpclog.PrefixLogger // Prefix logger for all logging.
9596

9697
// childMu synchronizes calls to any single child. It must be held for all
9798
// calls into a child. To avoid deadlocks, do not acquire childMu while
@@ -220,11 +221,8 @@ func (es *endpointSharding) ExitIdle() {
220221
// exitidle (but still checks for the interface's existence to
221222
// avoid a panic if not). If the child does not, no subconns
222223
// will be connected.
223-
ei, ok := bw.child.(balancer.ExitIdler)
224-
if ok && !bw.isClosed {
225-
ei.ExitIdle()
226-
} else if !ok {
227-
es.logger.Errorf("Child balancer doesn't implement ExitIdler.")
224+
if !bw.isClosed {
225+
bw.child.ExitIdle()
228226
}
229227
}
230228
}
@@ -350,21 +348,13 @@ func (bw *balancerWrapper) UpdateState(state balancer.State) {
350348
// ExitIdle pings an IDLE child balancer to exit idle in a new goroutine to
351349
// avoid deadlocks due to synchronous balancer state updates.
352350
func (bw *balancerWrapper) ExitIdle() {
353-
// this implementation assumes the child balancer supports
354-
// exitidle (but still checks for the interface's existence to
355-
// avoid a panic if not). If the child does not, no subconns
356-
// will be connected.
357-
if ei, ok := bw.child.(balancer.ExitIdler); ok {
358-
go func() {
359-
bw.es.childMu.Lock()
360-
if !bw.isClosed {
361-
ei.ExitIdle()
362-
}
363-
bw.es.childMu.Unlock()
364-
}()
365-
} else if !ok {
366-
bw.es.logger.Errorf("Child balancer doesn't implement ExitIdler.")
367-
}
351+
go func() {
352+
bw.es.childMu.Lock()
353+
if !bw.isClosed {
354+
bw.child.ExitIdle()
355+
}
356+
bw.es.childMu.Unlock()
357+
}()
368358
}
369359

370360
// updateClientConnStateLocked delivers the ClientConnState to the child

balancer/endpointsharding/endpointsharding_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ type fakePetiole struct {
103103
}
104104

105105
func (fp *fakePetiole) ExitIdle() {
106-
fp.Balancer.(balancer.ExitIdler).ExitIdle()
106+
fp.Balancer.(balancer.Balancer).ExitIdle()
107107
}
108108

109109
func (fp *fakePetiole) UpdateClientConnState(state balancer.ClientConnState) error {
@@ -316,7 +316,7 @@ func (s) TestEndpointShardingExitIdle(t *testing.T) {
316316
bd.Data.(balancer.Balancer).Close()
317317
},
318318
ExitIdle: func(bd *stub.BalancerData) {
319-
bd.Data.(balancer.ExitIdler).ExitIdle()
319+
bd.Data.(balancer.Balancer).ExitIdle()
320320
},
321321
}
322322
stub.Register(name, bf)

balancer/lazy/lazy.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,7 @@ func (lb *lazyBalancer) ExitIdle() {
125125
lb.mu.Lock()
126126
defer lb.mu.Unlock()
127127
if lb.delegate != nil {
128-
if d, ok := lb.delegate.(balancer.ExitIdler); ok {
129-
d.ExitIdle()
130-
}
128+
lb.delegate.ExitIdle()
131129
return
132130
}
133131
lb.delegate = lb.childBuilder(lb.cc, lb.buildOptions)

balancer/lazy/lazy_ext_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func (s) TestExitIdle(t *testing.T) {
8282
bd.Data = lazy.NewBalancer(bd.ClientConn, bd.BuildOptions, balancer.Get(pickfirstleaf.Name).Build)
8383
},
8484
ExitIdle: func(bd *stub.BalancerData) {
85-
bd.Data.(balancer.ExitIdler).ExitIdle()
85+
bd.Data.(balancer.Balancer).ExitIdle()
8686
},
8787
ResolverError: func(bd *stub.BalancerData, err error) {
8888
bd.Data.(balancer.Balancer).ResolverError(err)
@@ -410,7 +410,7 @@ func (s) TestExitIdlePassthrough(t *testing.T) {
410410
bd.Data = lazy.NewBalancer(bd.ClientConn, bd.BuildOptions, balancer.Get(pickfirstleaf.Name).Build)
411411
},
412412
ExitIdle: func(bd *stub.BalancerData) {
413-
bd.Data.(balancer.ExitIdler).ExitIdle()
413+
bd.Data.(balancer.Balancer).ExitIdle()
414414
},
415415
ResolverError: func(bd *stub.BalancerData, err error) {
416416
bd.Data.(balancer.Balancer).ResolverError(err)

balancer/leastrequest/leastrequest.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,7 @@ func (lrb *leastRequestBalancer) ResolverError(err error) {
125125
}
126126

127127
func (lrb *leastRequestBalancer) ExitIdle() {
128-
if ei, ok := lrb.child.(balancer.ExitIdler); ok { // Should always be ok, as child is endpoint sharding.
129-
ei.ExitIdle()
130-
} else {
131-
lrb.logger.Errorf("Child balancer doesn't implement ExitIdler.")
132-
}
128+
lrb.child.ExitIdle()
133129
}
134130

135131
func (lrb *leastRequestBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {

balancer/pickfirst/pickfirstleaf/pickfirstleaf_ext_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,7 @@ func (b *stateStoringBalancer) Close() {
15931593
}
15941594

15951595
func (b *stateStoringBalancer) ExitIdle() {
1596-
b.Balancer.(balancer.ExitIdler).ExitIdle()
1596+
b.Balancer.ExitIdle()
15971597
}
15981598

15991599
type stateStoringBalancerBuilder struct {

balancer/ringhash/ringhash.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ func (b *ringhashBalancer) updatePickerLocked() {
263263
sort.Slice(endpointStates, func(i, j int) bool {
264264
return endpointStates[i].hashKey < endpointStates[j].hashKey
265265
})
266-
var idleBalancer balancer.ExitIdler
266+
var idleBalancer endpointsharding.ExitIdler
267267
for _, es := range endpointStates {
268268
connState := es.state.ConnectivityState
269269
if connState == connectivity.Connecting {
@@ -394,7 +394,7 @@ type endpointState struct {
394394
// overridden, for example based on EDS endpoint metadata.
395395
hashKey string
396396
weight uint32
397-
balancer balancer.ExitIdler
397+
balancer endpointsharding.ExitIdler
398398

399399
// state is updated by the balancer while receiving resolver updates from
400400
// the channel and picker updates from its children. Access to it is guarded

balancer/rls/internal/test/e2e/rls_child_policy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ type RLSChildPolicyConfig struct {
103103
}
104104

105105
func (b *bal) ExitIdle() {
106-
b.Balancer.(balancer.ExitIdler).ExitIdle()
106+
b.Balancer.ExitIdle()
107107
}
108108

109109
func (b *bal) UpdateClientConnState(c balancer.ClientConnState) error {

balancer/roundrobin/roundrobin.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,5 @@ func (b *rrBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {
7272
}
7373

7474
func (b *rrBalancer) ExitIdle() {
75-
// Should always be ok, as child is endpoint sharding.
76-
if ei, ok := b.Balancer.(balancer.ExitIdler); ok {
77-
ei.ExitIdle()
78-
} else {
79-
b.logger.Errorf("Child balancer doesn't implement ExitIdler.")
80-
}
75+
b.Balancer.ExitIdle()
8176
}

0 commit comments

Comments
 (0)