Skip to content

Commit 25e2845

Browse files
authored
Merge pull request #2456 from murgatroid99/grpc-js_minor_fixes
grpc-js: Fix a couple of things that came up while investigating a memory leak
2 parents bcd52c1 + 2b455e7 commit 25e2845

File tree

3 files changed

+31
-15
lines changed

3 files changed

+31
-15
lines changed

packages/grpc-js/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@grpc/grpc-js",
3-
"version": "1.8.14",
3+
"version": "1.8.15",
44
"description": "gRPC Library for Node - pure JS implementation",
55
"homepage": "https://grpc.io/",
66
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",

packages/grpc-js/src/client.ts

+24-12
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ export class Client {
323323
emitter.call = call;
324324
let responseMessage: ResponseType | null = null;
325325
let receivedStatus = false;
326-
const callerStackError = new Error();
326+
let callerStackError: Error | null = new Error();
327327
call.start(callProperties.metadata, {
328328
onReceiveMetadata: (metadata) => {
329329
emitter.emit('metadata', metadata);
@@ -342,19 +342,22 @@ export class Client {
342342
receivedStatus = true;
343343
if (status.code === Status.OK) {
344344
if (responseMessage === null) {
345-
const callerStack = getErrorStackString(callerStackError);
345+
const callerStack = getErrorStackString(callerStackError!);
346346
callProperties.callback!(callErrorFromStatus({
347347
code: Status.INTERNAL,
348348
details: 'No message received',
349349
metadata: status.metadata
350-
}, callerStack));
350+
}, /*callerStack*/''));
351351
} else {
352352
callProperties.callback!(null, responseMessage);
353353
}
354354
} else {
355-
const callerStack = getErrorStackString(callerStackError);
356-
callProperties.callback!(callErrorFromStatus(status, callerStack));
355+
const callerStack = getErrorStackString(callerStackError!);
356+
callProperties.callback!(callErrorFromStatus(status, /*callerStack*/''));
357357
}
358+
/* Avoid retaining the callerStackError object in the call context of
359+
* the status event handler. */
360+
callerStackError = null;
358361
emitter.emit('status', status);
359362
},
360363
});
@@ -448,7 +451,7 @@ export class Client {
448451
emitter.call = call;
449452
let responseMessage: ResponseType | null = null;
450453
let receivedStatus = false;
451-
const callerStackError = new Error();
454+
let callerStackError: Error | null = new Error();
452455
call.start(callProperties.metadata, {
453456
onReceiveMetadata: (metadata) => {
454457
emitter.emit('metadata', metadata);
@@ -467,7 +470,7 @@ export class Client {
467470
receivedStatus = true;
468471
if (status.code === Status.OK) {
469472
if (responseMessage === null) {
470-
const callerStack = getErrorStackString(callerStackError);
473+
const callerStack = getErrorStackString(callerStackError!);
471474
callProperties.callback!(callErrorFromStatus({
472475
code: Status.INTERNAL,
473476
details: 'No message received',
@@ -477,9 +480,12 @@ export class Client {
477480
callProperties.callback!(null, responseMessage);
478481
}
479482
} else {
480-
const callerStack = getErrorStackString(callerStackError);
483+
const callerStack = getErrorStackString(callerStackError!);
481484
callProperties.callback!(callErrorFromStatus(status, callerStack));
482485
}
486+
/* Avoid retaining the callerStackError object in the call context of
487+
* the status event handler. */
488+
callerStackError = null;
483489
emitter.emit('status', status);
484490
},
485491
});
@@ -577,7 +583,7 @@ export class Client {
577583
* call after that. */
578584
stream.call = call;
579585
let receivedStatus = false;
580-
const callerStackError = new Error();
586+
let callerStackError: Error | null = new Error();
581587
call.start(callProperties.metadata, {
582588
onReceiveMetadata(metadata: Metadata) {
583589
stream.emit('metadata', metadata);
@@ -593,9 +599,12 @@ export class Client {
593599
receivedStatus = true;
594600
stream.push(null);
595601
if (status.code !== Status.OK) {
596-
const callerStack = getErrorStackString(callerStackError);
602+
const callerStack = getErrorStackString(callerStackError!);
597603
stream.emit('error', callErrorFromStatus(status, callerStack));
598604
}
605+
/* Avoid retaining the callerStackError object in the call context of
606+
* the status event handler. */
607+
callerStackError = null;
599608
stream.emit('status', status);
600609
},
601610
});
@@ -673,7 +682,7 @@ export class Client {
673682
* call after that. */
674683
stream.call = call;
675684
let receivedStatus = false;
676-
const callerStackError = new Error();
685+
let callerStackError: Error | null = new Error();
677686
call.start(callProperties.metadata, {
678687
onReceiveMetadata(metadata: Metadata) {
679688
stream.emit('metadata', metadata);
@@ -688,9 +697,12 @@ export class Client {
688697
receivedStatus = true;
689698
stream.push(null);
690699
if (status.code !== Status.OK) {
691-
const callerStack = getErrorStackString(callerStackError);
700+
const callerStack = getErrorStackString(callerStackError!);
692701
stream.emit('error', callErrorFromStatus(status, callerStack));
693702
}
703+
/* Avoid retaining the callerStackError object in the call context of
704+
* the status event handler. */
705+
callerStackError = null;
694706
stream.emit('status', status);
695707
},
696708
});

packages/grpc-js/src/load-balancing-call.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,18 @@ export class LoadBalancingCall implements Call {
216216
break;
217217
case PickResultType.DROP:
218218
const {code, details} = restrictControlPlaneStatusCode(pickResult.status!.code, pickResult.status!.details);
219-
this.outputStatus({code, details, metadata: pickResult.status!.metadata}, 'DROP');
219+
setImmediate(() => {
220+
this.outputStatus({code, details, metadata: pickResult.status!.metadata}, 'DROP');
221+
});
220222
break;
221223
case PickResultType.TRANSIENT_FAILURE:
222224
if (this.metadata.getOptions().waitForReady) {
223225
this.channel.queueCallForPick(this);
224226
} else {
225227
const {code, details} = restrictControlPlaneStatusCode(pickResult.status!.code, pickResult.status!.details);
226-
this.outputStatus({code, details, metadata: pickResult.status!.metadata}, 'PROCESSED');
228+
setImmediate(() => {
229+
this.outputStatus({code, details, metadata: pickResult.status!.metadata}, 'PROCESSED');
230+
});
227231
}
228232
break;
229233
case PickResultType.QUEUE:

0 commit comments

Comments
 (0)