@@ -105,7 +105,12 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error {
105
105
addrsSet .Set (a , nil )
106
106
if _ , ok := b .subConns .Get (a ); ! ok {
107
107
// a is a new address (not existing in b.subConns).
108
- sc , err := b .cc .NewSubConn ([]resolver.Address {a }, balancer.NewSubConnOptions {HealthCheckEnabled : b .config .HealthCheck })
108
+ var sc balancer.SubConn
109
+ opts := balancer.NewSubConnOptions {
110
+ HealthCheckEnabled : b .config .HealthCheck ,
111
+ StateListener : func (scs balancer.SubConnState ) { b .updateSubConnState (sc , scs ) },
112
+ }
113
+ sc , err := b .cc .NewSubConn ([]resolver.Address {a }, opts )
109
114
if err != nil {
110
115
logger .Warningf ("base.baseBalancer: failed to create new SubConn: %v" , err )
111
116
continue
@@ -121,10 +126,10 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error {
121
126
sc := sci .(balancer.SubConn )
122
127
// a was removed by resolver.
123
128
if _ , ok := addrsSet .Get (a ); ! ok {
124
- b . cc . RemoveSubConn ( sc )
129
+ sc . Shutdown ( )
125
130
b .subConns .Delete (a )
126
131
// Keep the state of this sc in b.scStates until sc's state becomes Shutdown.
127
- // The entry will be deleted in UpdateSubConnState .
132
+ // The entry will be deleted in updateSubConnState .
128
133
}
129
134
}
130
135
// If resolver state contains no addresses, return an error so ClientConn
@@ -177,7 +182,12 @@ func (b *baseBalancer) regeneratePicker() {
177
182
b .picker = b .pickerBuilder .Build (PickerBuildInfo {ReadySCs : readySCs })
178
183
}
179
184
185
+ // UpdateSubConnState is a nop because a StateListener is always set in NewSubConn.
180
186
func (b * baseBalancer ) UpdateSubConnState (sc balancer.SubConn , state balancer.SubConnState ) {
187
+ logger .Errorf ("base.baseBalancer: UpdateSubConnState(%v, %+v) called unexpectedly" , sc , state )
188
+ }
189
+
190
+ func (b * baseBalancer ) updateSubConnState (sc balancer.SubConn , state balancer.SubConnState ) {
181
191
s := state .ConnectivityState
182
192
if logger .V (2 ) {
183
193
logger .Infof ("base.baseBalancer: handle SubConn state change: %p, %v" , sc , s )
@@ -204,8 +214,8 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su
204
214
case connectivity .Idle :
205
215
sc .Connect ()
206
216
case connectivity .Shutdown :
207
- // When an address was removed by resolver, b called RemoveSubConn but
208
- // kept the sc's state in scStates. Remove state for this sc here.
217
+ // When an address was removed by resolver, b called Shutdown but kept
218
+ // the sc's state in scStates. Remove state for this sc here.
209
219
delete (b .scStates , sc )
210
220
case connectivity .TransientFailure :
211
221
// Save error to be reported via picker.
@@ -226,7 +236,7 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su
226
236
}
227
237
228
238
// Close is a nop because base balancer doesn't have internal state to clean up,
229
- // and it doesn't need to call RemoveSubConn for the SubConns.
239
+ // and it doesn't need to call Shutdown for the SubConns.
230
240
func (b * baseBalancer ) Close () {
231
241
}
232
242
0 commit comments