@@ -60,7 +60,7 @@ export class Subchannel {
60
60
* state changes. Will be modified by `addConnectivityStateListener` and
61
61
* `removeConnectivityStateListener`
62
62
*/
63
- private stateListeners : ConnectivityStateListener [ ] = [ ] ;
63
+ private stateListeners : Set < ConnectivityStateListener > = new Set ( ) ;
64
64
65
65
private backoffTimeout : BackoffTimeout ;
66
66
@@ -227,6 +227,8 @@ export class Subchannel {
227
227
}
228
228
const previousState = this . connectivityState ;
229
229
this . connectivityState = newState ;
230
+ process . nextTick ( ( ) => {
231
+ } ) ;
230
232
switch ( newState ) {
231
233
case ConnectivityState . READY :
232
234
this . stopBackoff ( ) ;
@@ -261,9 +263,7 @@ export class Subchannel {
261
263
default :
262
264
throw new Error ( `Invalid state: unknown ConnectivityState ${ newState } ` ) ;
263
265
}
264
- /* We use a shallow copy of the stateListeners array in case a listener
265
- * is removed during this iteration */
266
- for ( const listener of [ ...this . stateListeners ] ) {
266
+ for ( const listener of this . stateListeners ) {
267
267
listener ( this , previousState , newState , this . keepaliveTime ) ;
268
268
}
269
269
return true ;
@@ -291,13 +291,15 @@ export class Subchannel {
291
291
if ( this . channelzEnabled ) {
292
292
this . channelzTrace . addTrace ( 'CT_INFO' , 'Shutting down' ) ;
293
293
}
294
- this . transitionToState (
295
- [ ConnectivityState . CONNECTING , ConnectivityState . READY ] ,
296
- ConnectivityState . IDLE
297
- ) ;
298
294
if ( this . channelzEnabled ) {
299
295
unregisterChannelzRef ( this . channelzRef ) ;
300
296
}
297
+ process . nextTick ( ( ) => {
298
+ this . transitionToState (
299
+ [ ConnectivityState . CONNECTING , ConnectivityState . READY ] ,
300
+ ConnectivityState . IDLE
301
+ ) ;
302
+ } ) ;
301
303
}
302
304
}
303
305
@@ -339,20 +341,22 @@ export class Subchannel {
339
341
* Otherwise, do nothing.
340
342
*/
341
343
startConnecting ( ) {
342
- /* First, try to transition from IDLE to connecting. If that doesn't happen
343
- * because the state is not currently IDLE, check if it is
344
- * TRANSIENT_FAILURE, and if so indicate that it should go back to
345
- * connecting after the backoff timer ends. Otherwise do nothing */
346
- if (
347
- ! this . transitionToState (
348
- [ ConnectivityState . IDLE ] ,
349
- ConnectivityState . CONNECTING
350
- )
351
- ) {
352
- if ( this . connectivityState === ConnectivityState . TRANSIENT_FAILURE ) {
353
- this . continueConnecting = true ;
344
+ process . nextTick ( ( ) => {
345
+ /* First, try to transition from IDLE to connecting. If that doesn't happen
346
+ * because the state is not currently IDLE, check if it is
347
+ * TRANSIENT_FAILURE, and if so indicate that it should go back to
348
+ * connecting after the backoff timer ends. Otherwise do nothing */
349
+ if (
350
+ ! this . transitionToState (
351
+ [ ConnectivityState . IDLE ] ,
352
+ ConnectivityState . CONNECTING
353
+ )
354
+ ) {
355
+ if ( this . connectivityState === ConnectivityState . TRANSIENT_FAILURE ) {
356
+ this . continueConnecting = true ;
357
+ }
354
358
}
355
- }
359
+ } ) ;
356
360
}
357
361
358
362
/**
@@ -368,7 +372,7 @@ export class Subchannel {
368
372
* @param listener
369
373
*/
370
374
addConnectivityStateListener ( listener : ConnectivityStateListener ) {
371
- this . stateListeners . push ( listener ) ;
375
+ this . stateListeners . add ( listener ) ;
372
376
}
373
377
374
378
/**
@@ -377,21 +381,20 @@ export class Subchannel {
377
381
* `addConnectivityStateListener`
378
382
*/
379
383
removeConnectivityStateListener ( listener : ConnectivityStateListener ) {
380
- const listenerIndex = this . stateListeners . indexOf ( listener ) ;
381
- if ( listenerIndex > - 1 ) {
382
- this . stateListeners . splice ( listenerIndex , 1 ) ;
383
- }
384
+ this . stateListeners . delete ( listener ) ;
384
385
}
385
386
386
387
/**
387
388
* Reset the backoff timeout, and immediately start connecting if in backoff.
388
389
*/
389
390
resetBackoff ( ) {
390
- this . backoffTimeout . reset ( ) ;
391
- this . transitionToState (
392
- [ ConnectivityState . TRANSIENT_FAILURE ] ,
393
- ConnectivityState . CONNECTING
394
- ) ;
391
+ process . nextTick ( ( ) => {
392
+ this . backoffTimeout . reset ( ) ;
393
+ this . transitionToState (
394
+ [ ConnectivityState . TRANSIENT_FAILURE ] ,
395
+ ConnectivityState . CONNECTING
396
+ ) ;
397
+ } ) ;
395
398
}
396
399
397
400
getAddress ( ) : string {
0 commit comments