@@ -21,7 +21,7 @@ import {promisify} from 'util';
2121
2222import { ChannelRef } from './channel_ref' ;
2323import * as protoRoot from './generated/grpc_gcp' ;
24-
24+ import { connectivityState } from '@grpc/grpc-js' ;
2525import ApiConfig = protoRoot . grpc . gcp . ApiConfig ;
2626import IAffinityConfig = protoRoot . grpc . gcp . IAffinityConfig ;
2727
@@ -34,6 +34,8 @@ export interface GcpChannelFactoryInterface extends grpcType.ChannelInterface {
3434 getAffinityConfig ( methodName : string ) : IAffinityConfig ;
3535 bind ( channelRef : ChannelRef , affinityKey : string ) : void ;
3636 unbind ( boundKey ?: string ) : void ;
37+ shouldRequestDebugHeaders ( lastRequested : Date | null ) : boolean ;
38+
3739}
3840
3941export interface GcpChannelFactoryConstructor {
@@ -61,6 +63,7 @@ export function getGcpChannelFactoryClass(
6163 private channelRefs : ChannelRef [ ] = [ ] ;
6264 private target : string ;
6365 private credentials : grpcType . ChannelCredentials ;
66+ private debugHeaderIntervalSecs : number ;
6467
6568 /**
6669 * @param address The address of the server to connect to.
@@ -84,6 +87,7 @@ export function getGcpChannelFactoryClass(
8487 this . minSize = 1 ;
8588 this . maxSize = 10 ;
8689 this . maxConcurrentStreamsLowWatermark = 100 ;
90+ this . debugHeaderIntervalSecs = 0 ;
8791 const gcpApiConfig = options . gcpApiConfig ;
8892 if ( gcpApiConfig ) {
8993 if ( gcpApiConfig . channelPool ) {
@@ -98,6 +102,7 @@ export function getGcpChannelFactoryClass(
98102 if ( this . maxSize < this . minSize ) {
99103 throw new Error ( 'Invalid channelPool config: minSize must <= maxSize' )
100104 }
105+ this . debugHeaderIntervalSecs = channelPool . debugHeaderIntervalSecs || 0 ;
101106 }
102107 this . initMethodToAffinityMap ( gcpApiConfig ) ;
103108 }
@@ -187,9 +192,33 @@ export function getGcpChannelFactoryClass(
187192 ) ;
188193 const channelRef = new ChannelRef ( grpcChannel , size ) ;
189194 this . channelRefs . push ( channelRef ) ;
195+
196+ if ( this . debugHeaderIntervalSecs ) {
197+ this . setupDebugHeadersOnChannelTransition ( channelRef ) ;
198+ }
199+
190200 return channelRef ;
191201 }
192202
203+ private setupDebugHeadersOnChannelTransition ( channel : ChannelRef ) {
204+ const self = this ;
205+
206+ if ( channel . isClosed ( ) ) {
207+ return ;
208+ }
209+
210+ let currentState = channel . getChannel ( ) . getConnectivityState ( false ) ;
211+ if ( currentState == connectivityState . SHUTDOWN ) {
212+ return ;
213+ }
214+
215+ channel . getChannel ( ) . watchConnectivityState ( currentState , Infinity , ( e ) => {
216+ channel . forceDebugHeadersOnNextRequest ( ) ;
217+ self . setupDebugHeadersOnChannelTransition ( channel ) ;
218+ } ) ;
219+ }
220+
221+
193222 /**
194223 * Get AffinityConfig associated with a certain method.
195224 * @param methodName Method name of the request.
@@ -198,6 +227,14 @@ export function getGcpChannelFactoryClass(
198227 return this . methodToAffinity [ methodName ] ;
199228 }
200229
230+ shouldRequestDebugHeaders ( lastRequested : Date | null ) : boolean {
231+ if ( this . debugHeaderIntervalSecs < 0 ) return true ;
232+ else if ( this . debugHeaderIntervalSecs == 0 ) return false ;
233+ else if ( ! lastRequested ) return true ;
234+
235+ return new Date ( ) . getTime ( ) - lastRequested . getTime ( ) > this . debugHeaderIntervalSecs * 1000 ;
236+ }
237+
201238 /**
202239 * Bind channel with affinity key.
203240 * @param channelRef ChannelRef instance that contains the grpc channel.
@@ -232,7 +269,7 @@ export function getGcpChannelFactoryClass(
232269 */
233270 close ( ) : void {
234271 this . channelRefs . forEach ( ref => {
235- ref . getChannel ( ) . close ( ) ;
272+ ref . close ( ) ;
236273 } ) ;
237274 }
238275
0 commit comments