@@ -20,7 +20,7 @@ import { ChannelOptions } from './channel-options';
20
20
import { ResolvingLoadBalancer } from './resolving-load-balancer' ;
21
21
import { SubchannelPool , getSubchannelPool } from './subchannel-pool' ;
22
22
import { ChannelControlHelper } from './load-balancer' ;
23
- import { UnavailablePicker , Picker , QueuePicker } from './picker' ;
23
+ import { UnavailablePicker , Picker , QueuePicker , PickArgs , PickResult , PickResultType } from './picker' ;
24
24
import { Metadata } from './metadata' ;
25
25
import { Status , LogVerbosity , Propagate } from './constants' ;
26
26
import { FilterStackFactory } from './filter-stack' ;
@@ -143,6 +143,22 @@ class ChannelSubchannelWrapper
143
143
}
144
144
}
145
145
146
+ class ShutdownPicker implements Picker {
147
+ pick ( pickArgs : PickArgs ) : PickResult {
148
+ return {
149
+ pickResultType : PickResultType . DROP ,
150
+ status : {
151
+ code : Status . UNAVAILABLE ,
152
+ details : 'Channel closed before call started' ,
153
+ metadata : new Metadata ( )
154
+ } ,
155
+ subchannel : null ,
156
+ onCallStarted : null ,
157
+ onCallEnded : null
158
+ }
159
+ }
160
+ }
161
+
146
162
export class InternalChannel {
147
163
private readonly resolvingLoadBalancer : ResolvingLoadBalancer ;
148
164
private readonly subchannelPool : SubchannelPool ;
@@ -536,7 +552,9 @@ export class InternalChannel {
536
552
}
537
553
538
554
getConfig ( method : string , metadata : Metadata ) : GetConfigResult {
539
- this . resolvingLoadBalancer . exitIdle ( ) ;
555
+ if ( this . connectivityState !== ConnectivityState . SHUTDOWN ) {
556
+ this . resolvingLoadBalancer . exitIdle ( ) ;
557
+ }
540
558
if ( this . configSelector ) {
541
559
return {
542
560
type : 'SUCCESS' ,
@@ -745,6 +763,15 @@ export class InternalChannel {
745
763
close ( ) {
746
764
this . resolvingLoadBalancer . destroy ( ) ;
747
765
this . updateState ( ConnectivityState . SHUTDOWN ) ;
766
+ this . currentPicker = new ShutdownPicker ( ) ;
767
+ for ( const call of this . configSelectionQueue ) {
768
+ call . cancelWithStatus ( Status . UNAVAILABLE , 'Channel closed before call started' ) ;
769
+ }
770
+ this . configSelectionQueue = [ ] ;
771
+ for ( const call of this . pickQueue ) {
772
+ call . cancelWithStatus ( Status . UNAVAILABLE , 'Channel closed before call started' ) ;
773
+ }
774
+ this . pickQueue = [ ] ;
748
775
clearInterval ( this . callRefTimer ) ;
749
776
if ( this . idleTimer ) {
750
777
clearTimeout ( this . idleTimer ) ;
0 commit comments