@@ -174,6 +174,12 @@ export class PickFirstLoadBalancer implements LoadBalancer {
174
174
*/
175
175
private stickyTransientFailureMode = false ;
176
176
177
+ /**
178
+ * Indicates whether we called channelControlHelper.requestReresolution since
179
+ * the last call to updateAddressList
180
+ */
181
+ private requestedResolutionSinceLastUpdate = false ;
182
+
177
183
/**
178
184
* The most recent error reported by any subchannel as it transitioned to
179
185
* TRANSIENT_FAILURE.
@@ -216,15 +222,28 @@ export class PickFirstLoadBalancer implements LoadBalancer {
216
222
}
217
223
}
218
224
225
+ private requestReresolution ( ) {
226
+ this . requestedResolutionSinceLastUpdate = true ;
227
+ this . channelControlHelper . requestReresolution ( ) ;
228
+ }
229
+
219
230
private maybeEnterStickyTransientFailureMode ( ) {
220
- if ( this . stickyTransientFailureMode ) {
231
+ if ( ! this . allChildrenHaveReportedTF ( ) ) {
221
232
return ;
222
233
}
223
- if ( ! this . allChildrenHaveReportedTF ( ) ) {
234
+ if ( ! this . requestedResolutionSinceLastUpdate ) {
235
+ /* Each time we get an update we reset each subchannel's
236
+ * hasReportedTransientFailure flag, so the next time we get to this
237
+ * point after that, each subchannel has reported TRANSIENT_FAILURE
238
+ * at least once since then. That is the trigger for requesting
239
+ * reresolution, whether or not the LB policy is already in sticky TF
240
+ * mode. */
241
+ this . requestReresolution ( ) ;
242
+ }
243
+ if ( this . stickyTransientFailureMode ) {
224
244
return ;
225
245
}
226
246
this . stickyTransientFailureMode = true ;
227
- this . channelControlHelper . requestReresolution ( ) ;
228
247
for ( const { subchannel } of this . children ) {
229
248
subchannel . startConnecting ( ) ;
230
249
}
@@ -256,7 +275,7 @@ export class PickFirstLoadBalancer implements LoadBalancer {
256
275
if ( newState !== ConnectivityState . READY ) {
257
276
this . removeCurrentPick ( ) ;
258
277
this . calculateAndReportNewState ( ) ;
259
- this . channelControlHelper . requestReresolution ( ) ;
278
+ this . requestReresolution ( ) ;
260
279
}
261
280
return ;
262
281
}
@@ -283,7 +302,7 @@ export class PickFirstLoadBalancer implements LoadBalancer {
283
302
284
303
private startNextSubchannelConnecting ( startIndex : number ) {
285
304
clearTimeout ( this . connectionDelayTimeout ) ;
286
- if ( this . triedAllSubchannels || this . stickyTransientFailureMode ) {
305
+ if ( this . triedAllSubchannels ) {
287
306
return ;
288
307
}
289
308
for ( const [ index , child ] of this . children . entries ( ) ) {
@@ -382,6 +401,7 @@ export class PickFirstLoadBalancer implements LoadBalancer {
382
401
this . currentSubchannelIndex = 0 ;
383
402
this . children = [ ] ;
384
403
this . triedAllSubchannels = false ;
404
+ this . requestedResolutionSinceLastUpdate = false ;
385
405
}
386
406
387
407
updateAddressList (
0 commit comments