6
6
status as statusJS ,
7
7
} from '@grpc/grpc-js'
8
8
import { loadSync , Options , PackageDefinition } from '@grpc/proto-loader'
9
+ import * as _debug from 'debug'
9
10
import { EventEmitter } from 'events'
10
11
import {
11
12
Client ,
@@ -20,6 +21,8 @@ import { BasicAuthConfig } from './interfaces'
20
21
import { Loglevel } from './interfaces-published-contract'
21
22
import { OAuthProvider } from './OAuthProvider'
22
23
24
+ const debug = _debug . default ( 'grpc' )
25
+
23
26
const useJS = process . env . ZEEBE_NODE_PUREJS ?. toUpperCase ( ) === 'TRUE'
24
27
const credentials = useJS ? credentialsJS : credentialsC
25
28
const InterceptingCall = useJS ? InterceptingCallJS : InterceptingCallC
@@ -222,12 +225,16 @@ export class GrpcClient extends EventEmitter {
222
225
* The maximum time between subsequent connection attempts,
223
226
* in ms
224
227
*/
225
- 'grpc.max_reconnect_backoff_ms' : 30000 ,
228
+ 'grpc.max_reconnect_backoff_ms' : 10000 ,
226
229
/**
227
230
* The minimum time between subsequent connection attempts,
228
- * in ms
231
+ * in ms. Default is 1000ms, but this can cause an SSL Handshake failure.
232
+ * This causes an intermittent failure in the Worker-LongPoll test when run
233
+ * against Camunda Cloud.
234
+ * Raised to 5000ms.
235
+ * See: https://github.com/grpc/grpc/issues/8382#issuecomment-259482949
229
236
*/
230
- 'grpc.min_reconnect_backoff_ms' : 1000 ,
237
+ 'grpc.min_reconnect_backoff_ms' : 5000 ,
231
238
/**
232
239
* After a duration of this time the client/server
233
240
* pings its peer to see if the transport is still alive.
@@ -240,7 +247,7 @@ export class GrpcClient extends EventEmitter {
240
247
* not receive the ping ack, it will close the
241
248
* transport. Int valued, milliseconds.
242
249
*/
243
- 'grpc.keepalive_timeout_ms' : 60000 ,
250
+ 'grpc.keepalive_timeout_ms' : 120000 ,
244
251
'grpc.http2.min_time_between_pings_ms' : 60000 ,
245
252
/**
246
253
* Minimum allowed time between a server receiving
@@ -267,6 +274,12 @@ export class GrpcClient extends EventEmitter {
267
274
} )
268
275
this . listNameMethods = [ ]
269
276
277
+ this . client . waitForReady ( 10000 , error =>
278
+ error
279
+ ? this . emit ( MiddlewareSignals . Event . Error , error )
280
+ : this . emit ( MiddlewareSignals . Event . Ready )
281
+ )
282
+
270
283
for ( const key in listMethods ) {
271
284
if ( listMethods [ key ] ) {
272
285
const methodName = listMethods [ key ] . originalName as string
@@ -286,6 +299,7 @@ export class GrpcClient extends EventEmitter {
286
299
)
287
300
try {
288
301
const metadata = await this . getAuthToken ( )
302
+
289
303
stream = this . client [ methodName ] (
290
304
timeNormalisedRequest ,
291
305
metadata
@@ -304,6 +318,19 @@ export class GrpcClient extends EventEmitter {
304
318
) ,
305
319
}
306
320
}
321
+
322
+ // This deals with the case where during a broker restart the call returns a stream
323
+ // but that stream is not a legit Gateway activation. In that case, the Gateway will
324
+ // never time out or close the stream. So we have to manage that case.
325
+ const clientsideTimeoutDuration =
326
+ Duration . milliseconds . from ( this . longPoll ! ) + 1000
327
+ const clientSideTimeout = setTimeout ( ( ) => {
328
+ debug (
329
+ `Triggered client-side timeout after ${ clientsideTimeoutDuration } ms`
330
+ )
331
+ stream . emit ( 'end' )
332
+ } , clientsideTimeoutDuration )
333
+
307
334
/**
308
335
* Once this gets attached here, it is attached to *all* calls
309
336
* This is an issue if you do a sync call like cancelWorkflowSync
@@ -312,6 +339,8 @@ export class GrpcClient extends EventEmitter {
312
339
* streaming calls, and each worker, which only does streaming calls
313
340
*/
314
341
stream . on ( 'error' , ( error : GrpcStreamError ) => {
342
+ clearTimeout ( clientSideTimeout )
343
+ debug ( `Error` , error )
315
344
this . emit ( MiddlewareSignals . Event . Error )
316
345
if ( error . message . includes ( '14 UNAVAILABLE' ) ) {
317
346
this . emit (
@@ -341,6 +370,8 @@ export class GrpcClient extends EventEmitter {
341
370
`gRPC Status event: ${ JSON . stringify ( s ) } `
342
371
)
343
372
)
373
+ stream . on ( 'end' , ( ) => clearTimeout ( clientSideTimeout ) )
374
+
344
375
return stream
345
376
}
346
377
0 commit comments