Skip to content

Commit

Permalink
grpc-js: Avoid sending redundant RST_STREAMs from the client
Browse files Browse the repository at this point in the history
  • Loading branch information
murgatroid99 committed Mar 20, 2024
1 parent 649412f commit 14f1d02
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
2 changes: 1 addition & 1 deletion packages/grpc-js/package.json
@@ -1,6 +1,6 @@
{
"name": "@grpc/grpc-js",
"version": "1.10.3",
"version": "1.10.4",
"description": "gRPC Library for Node - pure JS implementation",
"homepage": "https://grpc.io/",
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",
Expand Down
14 changes: 13 additions & 1 deletion packages/grpc-js/src/subchannel-call.ts
Expand Up @@ -105,6 +105,8 @@ export class Http2SubchannelCall implements SubchannelCall {

private internalError: SystemError | null = null;

private serverEndedCall = false;

constructor(
private readonly http2Stream: http2.ClientHttp2Stream,
private readonly callEventTracker: CallEventTracker,
Expand Down Expand Up @@ -182,6 +184,7 @@ export class Http2SubchannelCall implements SubchannelCall {
this.maybeOutputStatus();
});
http2Stream.on('close', () => {
this.serverEndedCall = true;
/* Use process.next tick to ensure that this code happens after any
* "error" event that may be emitted at about the same time, so that
* we can bubble up the error message from that event. */
Expand Down Expand Up @@ -400,6 +403,7 @@ export class Http2SubchannelCall implements SubchannelCall {
}

private handleTrailers(headers: http2.IncomingHttpHeaders) {
this.serverEndedCall = true;
this.callEventTracker.onStreamEnd(true);
let headersString = '';
for (const header of Object.keys(headers)) {
Expand Down Expand Up @@ -445,7 +449,15 @@ export class Http2SubchannelCall implements SubchannelCall {
private destroyHttp2Stream() {
// The http2 stream could already have been destroyed if cancelWithStatus
// is called in response to an internal http2 error.
if (!this.http2Stream.destroyed) {
if (this.http2Stream.destroyed) {
return;
}
/* If the server ended the call, sending an RST_STREAM is redundant, so we
* just half close on the client side instead to finish closing the stream.
*/
if (this.serverEndedCall) {
this.http2Stream.end();
} else {
/* If the call has ended with an OK status, communicate that when closing
* the stream, partly to avoid a situation in which we detect an error
* RST_STREAM as a result after we have the status */
Expand Down

0 comments on commit 14f1d02

Please sign in to comment.