Skip to content

Commit e9359ef

Browse files
authored
Merge pull request #2862 from murgatroid99/grpc-js_connection_drop_reporting_changes
grpc-js: Improve event sequencing when handling connection drops
2 parents a524d15 + 5e3b0fb commit e9359ef

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-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.12.3",
3+
"version": "1.12.4",
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/subchannel-call.ts

+21-6
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ export class Http2SubchannelCall implements SubchannelCall {
140140

141141
private serverEndedCall = false;
142142

143+
private connectionDropped = false;
144+
143145
constructor(
144146
private readonly http2Stream: http2.ClientHttp2Stream,
145147
private readonly callEventTracker: CallEventTracker,
@@ -240,8 +242,16 @@ export class Http2SubchannelCall implements SubchannelCall {
240242
details = 'Stream refused by server';
241243
break;
242244
case http2.constants.NGHTTP2_CANCEL:
243-
code = Status.CANCELLED;
244-
details = 'Call cancelled';
245+
/* Bug reports indicate that Node synthesizes a NGHTTP2_CANCEL
246+
* code from connection drops. We want to prioritize reporting
247+
* an unavailable status when that happens. */
248+
if (this.connectionDropped) {
249+
code = Status.UNAVAILABLE;
250+
details = 'Connection dropped';
251+
} else {
252+
code = Status.CANCELLED;
253+
details = 'Call cancelled';
254+
}
245255
break;
246256
case http2.constants.NGHTTP2_ENHANCE_YOUR_CALM:
247257
code = Status.RESOURCE_EXHAUSTED;
@@ -321,10 +331,15 @@ export class Http2SubchannelCall implements SubchannelCall {
321331
}
322332

323333
public onDisconnect() {
324-
this.endCall({
325-
code: Status.UNAVAILABLE,
326-
details: 'Connection dropped',
327-
metadata: new Metadata(),
334+
this.connectionDropped = true;
335+
/* Give the call an event loop cycle to finish naturally before reporting
336+
* the disconnection as an error. */
337+
setImmediate(() => {
338+
this.endCall({
339+
code: Status.UNAVAILABLE,
340+
details: 'Connection dropped',
341+
metadata: new Metadata(),
342+
});
328343
});
329344
}
330345

packages/grpc-js/src/transport.ts

+4-8
Original file line numberDiff line numberDiff line change
@@ -387,17 +387,13 @@ class Http2Transport implements Transport {
387387
* Handle connection drops, but not GOAWAYs.
388388
*/
389389
private handleDisconnect() {
390-
if (this.disconnectHandled) {
391-
return;
392-
}
393390
this.clearKeepaliveTimeout();
394391
this.reportDisconnectToOwner(false);
395-
/* Give calls an event loop cycle to finish naturally before reporting the
396-
* disconnnection to them. */
392+
for (const call of this.activeCalls) {
393+
call.onDisconnect();
394+
}
395+
// Wait an event loop cycle before destroying the connection
397396
setImmediate(() => {
398-
for (const call of this.activeCalls) {
399-
call.onDisconnect();
400-
}
401397
this.session.destroy();
402398
});
403399
}

0 commit comments

Comments
 (0)