Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grpc-js: Avoid sending redundant RST_STREAMs from the client #2695

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/grpc-js/package.json
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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