Skip to content

Commit 2700efe

Browse files
committed
Address review comments
1 parent a68c372 commit 2700efe

File tree

2 files changed

+30
-21
lines changed

2 files changed

+30
-21
lines changed

balancer/pickfirst/pickfirstleaf/pickfirstleaf.go

+25-18
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import (
3333
"sync"
3434
"time"
3535

36-
"google.golang.org/grpc/attributes"
3736
"google.golang.org/grpc/balancer"
3837
"google.golang.org/grpc/balancer/pickfirst/internal"
3938
"google.golang.org/grpc/connectivity"
@@ -63,11 +62,6 @@ var (
6362
// It is changed to "pick_first" in init() if this balancer is to be
6463
// registered as the default pickfirst.
6564
Name = "pick_first_leaf"
66-
67-
// enableHealthListenerValue is the resolver state attribute value used to
68-
// enable pickfirst to listen for health updates when operating under a
69-
// petiole policy.
70-
enableHealthListenerValue = &struct{}{}
7165
)
7266

7367
const (
@@ -118,8 +112,9 @@ func (pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalan
118112

119113
// EnableHealthListener updates the state to configure pickfirst for using a
120114
// generic health listener.
121-
func EnableHealthListener(attrs *attributes.Attributes) *attributes.Attributes {
122-
return attrs.WithValue(enableHealthListenerKeyType{}, enableHealthListenerValue)
115+
func EnableHealthListener(state resolver.State) resolver.State {
116+
state.Attributes = state.Attributes.WithValue(enableHealthListenerKeyType{}, true)
117+
return state
123118
}
124119

125120
type pfConfig struct {
@@ -170,7 +165,10 @@ type pickfirstBalancer struct {
170165
// The mutex is used to ensure synchronization of updates triggered
171166
// from the idle picker and the already serialized resolver,
172167
// SubConn state updates.
173-
mu sync.Mutex
168+
mu sync.Mutex
169+
// The raw connectivity state based on SubConn state updates and resolver
170+
// updates, i.e. independent of SubConn health updates. It is tracked
171+
// separately to support the sticky TF behaviour described in A62.
174172
connectivityState connectivity.State
175173
// State reported to the channel. It will be the health state when being
176174
// used as a leaf policy and the connectivityState is READY.
@@ -227,7 +225,7 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState
227225
b.resolverErrorLocked(errors.New("produced zero addresses"))
228226
return balancer.ErrBadResolverState
229227
}
230-
b.healthCheckingEnabled = state.ResolverState.Attributes.Value(enableHealthListenerKeyType{}) == enableHealthListenerValue
228+
b.healthCheckingEnabled = state.ResolverState.Attributes.Value(enableHealthListenerKeyType{}).(bool)
231229
cfg, ok := state.BalancerConfig.(pfConfig)
232230
if state.BalancerConfig != nil && !ok {
233231
return fmt.Errorf("pickfirst: received illegal BalancerConfig (type %T): %v: %w", state.BalancerConfig, state.BalancerConfig, balancer.ErrBadResolverState)
@@ -564,7 +562,7 @@ func (b *pickfirstBalancer) updateSubConnState(sd *scData, newState balancer.Sub
564562
// To prevent pickers from returning these obsolete SubConns, this logic
565563
// is included to check if the current list of active SubConns includes this
566564
// SubConn.
567-
if activeSD, found := b.subConns.Get(sd.addr); !found || activeSD != sd {
565+
if !b.isActiveSCData(sd) {
568566
return
569567
}
570568
if newState.ConnectivityState == connectivity.Shutdown {
@@ -706,14 +704,19 @@ func (b *pickfirstBalancer) endFirstPassIfPossibleLocked(lastErr error) {
706704
}
707705
}
708706

707+
func (b *pickfirstBalancer) isActiveSCData(sd *scData) bool {
708+
activeSD, found := b.subConns.Get(sd.addr)
709+
return found && activeSD == sd
710+
}
711+
709712
func (b *pickfirstBalancer) updateSubConnHealthState(sd *scData, state balancer.SubConnState) {
710713
b.mu.Lock()
711714
defer b.mu.Unlock()
712715
// Previously relevant SubConns can still callback with state updates.
713716
// To prevent pickers from returning these obsolete SubConns, this logic
714717
// is included to check if the current list of active SubConns includes
715718
// this SubConn.
716-
if activeSD, found := b.subConns.Get(sd.addr); !found || activeSD != sd {
719+
if !b.isActiveSCData(sd) {
717720
return
718721
}
719722
switch state.ConnectivityState {
@@ -725,7 +728,7 @@ func (b *pickfirstBalancer) updateSubConnHealthState(sd *scData, state balancer.
725728
case connectivity.TransientFailure:
726729
b.updateConcludedStateLocked(balancer.State{
727730
ConnectivityState: connectivity.TransientFailure,
728-
Picker: &picker{err: fmt.Errorf("health check failure: %v", state.ConnectionError)},
731+
Picker: &picker{err: fmt.Errorf("pickfirst: health check failure: %v", state.ConnectionError)},
729732
})
730733
case connectivity.Connecting:
731734
b.updateConcludedStateLocked(balancer.State{
@@ -737,18 +740,22 @@ func (b *pickfirstBalancer) updateSubConnHealthState(sd *scData, state balancer.
737740
}
738741
}
739742

743+
// updateConcludedStateLocked stores the state reported to the channel and calls
744+
// ClientConn.UpdateState(). As an optimization, it avoid sending duplicate
745+
// updates to the channel for state CONNECTING.
740746
func (b *pickfirstBalancer) updateConcludedStateLocked(newState balancer.State) {
741-
// Optimization to not send duplicate CONNECTING and IDLE updates.
747+
// Optimization to not send duplicate CONNECTING updates.
742748
if newState.ConnectivityState == b.concludedState && b.concludedState == connectivity.Connecting {
743749
return
744750
}
745751
b.forceUpdateConcludedStateLocked(newState)
746752
}
747753

748-
// A separate function to force update the ClientConn state is required to send
749-
// the first CONNECTING update since the channel doesn't correctly assume that
750-
// LB policies start in CONNECTING and relies on LB policy to send an initial
751-
// CONNECTING update.
754+
// forceUpdateConcludedStateLocked stores the state reported to the channel and
755+
// calls ClientConn.UpdateState().
756+
// A separate function is defined to force update the ClientConn state since the
757+
// channel doesn't correctly assume that LB policies start in CONNECTING and
758+
// relies on LB policy to send an initial CONNECTING update.
752759
func (b *pickfirstBalancer) forceUpdateConcludedStateLocked(newState balancer.State) {
753760
b.concludedState = newState.ConnectivityState
754761
b.cc.UpdateState(newState)

balancer/pickfirst/pickfirstleaf/pickfirstleaf_ext_test.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,9 @@ func (s) TestPickFirstLeaf_InterleavingUnknownPreffered(t *testing.T) {
11701170
}
11711171

11721172
// Test verifies that pickfirst balancer transitions to READY when the health
1173-
// listener is enabled.
1173+
// listener is enabled. Since client side health checking is not enabled in
1174+
// the service config, the health listener will send a health update for READY
1175+
// after registering the listener.
11741176
func (s) TestPickFirstLeaf_HealthListenerEnabled(t *testing.T) {
11751177
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
11761178
defer cancel()
@@ -1182,7 +1184,7 @@ func (s) TestPickFirstLeaf_HealthListenerEnabled(t *testing.T) {
11821184
bd.Data.(balancer.Balancer).Close()
11831185
},
11841186
UpdateClientConnState: func(bd *stub.BalancerData, ccs balancer.ClientConnState) error {
1185-
ccs.ResolverState.Attributes = pickfirstleaf.EnableHealthListener(ccs.ResolverState.Attributes)
1187+
ccs.ResolverState = pickfirstleaf.EnableHealthListener(ccs.ResolverState)
11861188
return bd.Data.(balancer.Balancer).UpdateClientConnState(ccs)
11871189
},
11881190
}
@@ -1232,7 +1234,7 @@ func (s) TestPickFirstLeaf_HealthUpdates(t *testing.T) {
12321234
bd.Data.(balancer.Balancer).Close()
12331235
},
12341236
UpdateClientConnState: func(bd *stub.BalancerData, ccs balancer.ClientConnState) error {
1235-
ccs.ResolverState.Attributes = pickfirstleaf.EnableHealthListener(ccs.ResolverState.Attributes)
1237+
ccs.ResolverState = pickfirstleaf.EnableHealthListener(ccs.ResolverState)
12361238
return bd.Data.(balancer.Balancer).UpdateClientConnState(ccs)
12371239
},
12381240
}

0 commit comments

Comments
 (0)