@@ -50,6 +50,7 @@ import { Deadline, getDeadlineTimeoutString } from './deadline';
50
50
import { ResolvingCall } from './resolving-call' ;
51
51
import { getNextCallNumber } from './call-number' ;
52
52
import { restrictControlPlaneStatusCode } from './control-plane-status' ;
53
+ import { MessageBufferTracker , RetryingCall , RetryThrottler } from './retrying-call' ;
53
54
54
55
/**
55
56
* See https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_args
@@ -78,6 +79,11 @@ interface ErrorConfigResult {
78
79
79
80
type GetConfigResult = NoneConfigResult | SuccessConfigResult | ErrorConfigResult ;
80
81
82
+ const RETRY_THROTTLER_MAP : Map < string , RetryThrottler > = new Map ( ) ;
83
+
84
+ const DEFAULT_RETRY_BUFFER_SIZE_BYTES = 1 << 24 ; // 16 MB
85
+ const DEFAULT_PER_RPC_RETRY_BUFFER_SIZE_BYTES = 1 << 20 ; // 1 MB
86
+
81
87
export class InternalChannel {
82
88
83
89
private resolvingLoadBalancer : ResolvingLoadBalancer ;
@@ -111,6 +117,7 @@ export class InternalChannel {
111
117
* than TRANSIENT_FAILURE.
112
118
*/
113
119
private currentResolutionError : StatusObject | null = null ;
120
+ private retryBufferTracker : MessageBufferTracker ;
114
121
115
122
// Channelz info
116
123
private readonly channelzEnabled : boolean = true ;
@@ -179,6 +186,10 @@ export class InternalChannel {
179
186
this . subchannelPool = getSubchannelPool (
180
187
( options [ 'grpc.use_local_subchannel_pool' ] ?? 0 ) === 0
181
188
) ;
189
+ this . retryBufferTracker = new MessageBufferTracker (
190
+ options [ 'grpc.retry_buffer_size' ] ?? DEFAULT_RETRY_BUFFER_SIZE_BYTES ,
191
+ options [ 'grpc.per_rpc_retry_buffer_size' ] ?? DEFAULT_PER_RPC_RETRY_BUFFER_SIZE_BYTES
192
+ ) ;
182
193
const channelControlHelper : ChannelControlHelper = {
183
194
createSubchannel : (
184
195
subchannelAddress : SubchannelAddress ,
@@ -226,7 +237,12 @@ export class InternalChannel {
226
237
this . target ,
227
238
channelControlHelper ,
228
239
options ,
229
- ( configSelector ) => {
240
+ ( serviceConfig , configSelector ) => {
241
+ if ( serviceConfig . retryThrottling ) {
242
+ RETRY_THROTTLER_MAP . set ( this . getTarget ( ) , new RetryThrottler ( serviceConfig . retryThrottling . maxTokens , serviceConfig . retryThrottling . tokenRatio , RETRY_THROTTLER_MAP . get ( this . getTarget ( ) ) ) ) ;
243
+ } else {
244
+ RETRY_THROTTLER_MAP . delete ( this . getTarget ( ) ) ;
245
+ }
230
246
if ( this . channelzEnabled ) {
231
247
this . channelzTrace . addTrace ( 'CT_INFO' , 'Address resolution succeeded' ) ;
232
248
}
@@ -243,6 +259,7 @@ export class InternalChannel {
243
259
}
244
260
this . configSelectionQueue = [ ] ;
245
261
} ) ;
262
+
246
263
} ,
247
264
( status ) => {
248
265
if ( this . channelzEnabled ) {
@@ -405,6 +422,24 @@ export class InternalChannel {
405
422
return new LoadBalancingCall ( this , callConfig , method , host , credentials , deadline , callNumber ) ;
406
423
}
407
424
425
+ createRetryingCall (
426
+ callConfig : CallConfig ,
427
+ method : string ,
428
+ host : string ,
429
+ credentials : CallCredentials ,
430
+ deadline : Deadline
431
+ ) : RetryingCall {
432
+ const callNumber = getNextCallNumber ( ) ;
433
+ this . trace (
434
+ 'createRetryingCall [' +
435
+ callNumber +
436
+ '] method="' +
437
+ method +
438
+ '"'
439
+ ) ;
440
+ return new RetryingCall ( this , callConfig , method , host , credentials , deadline , callNumber , this . retryBufferTracker , RETRY_THROTTLER_MAP . get ( this . getTarget ( ) ) )
441
+ }
442
+
408
443
createInnerCall (
409
444
callConfig : CallConfig ,
410
445
method : string ,
@@ -413,7 +448,11 @@ export class InternalChannel {
413
448
deadline : Deadline
414
449
) : Call {
415
450
// Create a RetryingCall if retries are enabled
416
- return this . createLoadBalancingCall ( callConfig , method , host , credentials , deadline ) ;
451
+ if ( this . options [ 'grpc.enable_retries' ] === 0 ) {
452
+ return this . createLoadBalancingCall ( callConfig , method , host , credentials , deadline ) ;
453
+ } else {
454
+ return this . createRetryingCall ( callConfig , method , host , credentials , deadline ) ;
455
+ }
417
456
}
418
457
419
458
createResolvingCall (
@@ -439,7 +478,7 @@ export class InternalChannel {
439
478
parentCall : parentCall ,
440
479
} ;
441
480
442
- const call = new ResolvingCall ( this , method , finalOptions , this . filterStackFactory . clone ( ) , this . credentials . _getCallCredentials ( ) , getNextCallNumber ( ) ) ;
481
+ const call = new ResolvingCall ( this , method , finalOptions , this . filterStackFactory . clone ( ) , this . credentials . _getCallCredentials ( ) , callNumber ) ;
443
482
444
483
if ( this . channelzEnabled ) {
445
484
this . callTracker . addCallStarted ( ) ;
0 commit comments