Skip to content

Commit cd25bad

Browse files
authored
Merge pull request #2552 from murgatroid99/grpc-js_deferred_write_callback
grpc-js: Defer actions in http2 stream write callback
2 parents 53536d9 + 8896bfe commit cd25bad

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

packages/grpc-js/src/subchannel-call.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -501,16 +501,22 @@ export class Http2SubchannelCall implements SubchannelCall {
501501
sendMessageWithContext(context: MessageContext, message: Buffer) {
502502
this.trace('write() called with message of length ' + message.length);
503503
const cb: WriteCallback = (error?: Error | null) => {
504-
let code: Status = Status.UNAVAILABLE;
505-
if (
506-
(error as NodeJS.ErrnoException)?.code === 'ERR_STREAM_WRITE_AFTER_END'
507-
) {
508-
code = Status.INTERNAL;
509-
}
510-
if (error) {
511-
this.cancelWithStatus(code, `Write error: ${error.message}`);
512-
}
513-
context.callback?.();
504+
/* nextTick here ensures that no stream action can be taken in the call
505+
* stack of the write callback, in order to hopefully work around
506+
* https://github.com/nodejs/node/issues/49147 */
507+
process.nextTick(() => {
508+
let code: Status = Status.UNAVAILABLE;
509+
if (
510+
(error as NodeJS.ErrnoException)?.code ===
511+
'ERR_STREAM_WRITE_AFTER_END'
512+
) {
513+
code = Status.INTERNAL;
514+
}
515+
if (error) {
516+
this.cancelWithStatus(code, `Write error: ${error.message}`);
517+
}
518+
context.callback?.();
519+
});
514520
};
515521
this.trace('sending data chunk of length ' + message.length);
516522
this.callEventTracker.addMessageSent();

0 commit comments

Comments
 (0)