Skip to content

Commit

Permalink
Merge pull request #2862 from murgatroid99/grpc-js_connection_drop_re…
Browse files Browse the repository at this point in the history
…porting_changes

grpc-js: Improve event sequencing when handling connection drops
  • Loading branch information
murgatroid99 authored Dec 4, 2024
2 parents a524d15 + 5e3b0fb commit e9359ef
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 15 deletions.
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.12.3",
"version": "1.12.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
27 changes: 21 additions & 6 deletions packages/grpc-js/src/subchannel-call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ export class Http2SubchannelCall implements SubchannelCall {

private serverEndedCall = false;

private connectionDropped = false;

constructor(
private readonly http2Stream: http2.ClientHttp2Stream,
private readonly callEventTracker: CallEventTracker,
Expand Down Expand Up @@ -240,8 +242,16 @@ export class Http2SubchannelCall implements SubchannelCall {
details = 'Stream refused by server';
break;
case http2.constants.NGHTTP2_CANCEL:
code = Status.CANCELLED;
details = 'Call cancelled';
/* Bug reports indicate that Node synthesizes a NGHTTP2_CANCEL
* code from connection drops. We want to prioritize reporting
* an unavailable status when that happens. */
if (this.connectionDropped) {
code = Status.UNAVAILABLE;
details = 'Connection dropped';
} else {
code = Status.CANCELLED;
details = 'Call cancelled';
}
break;
case http2.constants.NGHTTP2_ENHANCE_YOUR_CALM:
code = Status.RESOURCE_EXHAUSTED;
Expand Down Expand Up @@ -321,10 +331,15 @@ export class Http2SubchannelCall implements SubchannelCall {
}

public onDisconnect() {
this.endCall({
code: Status.UNAVAILABLE,
details: 'Connection dropped',
metadata: new Metadata(),
this.connectionDropped = true;
/* Give the call an event loop cycle to finish naturally before reporting
* the disconnection as an error. */
setImmediate(() => {
this.endCall({
code: Status.UNAVAILABLE,
details: 'Connection dropped',
metadata: new Metadata(),
});
});
}

Expand Down
12 changes: 4 additions & 8 deletions packages/grpc-js/src/transport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,17 +387,13 @@ class Http2Transport implements Transport {
* Handle connection drops, but not GOAWAYs.
*/
private handleDisconnect() {
if (this.disconnectHandled) {
return;
}
this.clearKeepaliveTimeout();
this.reportDisconnectToOwner(false);
/* Give calls an event loop cycle to finish naturally before reporting the
* disconnnection to them. */
for (const call of this.activeCalls) {
call.onDisconnect();
}
// Wait an event loop cycle before destroying the connection
setImmediate(() => {
for (const call of this.activeCalls) {
call.onDisconnect();
}
this.session.destroy();
});
}
Expand Down

0 comments on commit e9359ef

Please sign in to comment.