Skip to content

Commit 981efb6

Browse files
committed
Merge remote-tracking branch 'upstream/@grpc/[email protected]' into v1.8.x_upmerge_again
2 parents af31ef0 + 18dacfa commit 981efb6

File tree

3 files changed

+55
-28
lines changed

3 files changed

+55
-28
lines changed

packages/grpc-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@grpc/grpc-js",
3-
"version": "1.8.18",
3+
"version": "1.8.19",
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/server-call.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -962,8 +962,8 @@ export class Http2ServerCallStream<
962962
}
963963

964964
getPeer(): string {
965-
const socket = this.stream.session.socket;
966-
if (socket.remoteAddress) {
965+
const socket = this.stream.session?.socket;
966+
if (socket?.remoteAddress) {
967967
if (socket.remotePort) {
968968
return `${socket.remoteAddress}:${socket.remotePort}`;
969969
} else {

packages/grpc-js/src/transport.ts

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,12 @@ class Http2Transport implements Transport {
108108
/**
109109
* Timer reference for timeout that indicates when to send the next ping
110110
*/
111-
private keepaliveIntervalId: NodeJS.Timer;
111+
private keepaliveTimerId: NodeJS.Timer | null = null;
112+
/**
113+
* Indicates that the keepalive timer ran out while there were no active
114+
* calls, and a ping should be sent the next time a call starts.
115+
*/
116+
private pendingSendKeepalivePing = false;
112117
/**
113118
* Timer reference tracking when the most recent ping will be considered lost
114119
*/
@@ -169,10 +174,8 @@ class Http2Transport implements Transport {
169174
} else {
170175
this.keepaliveWithoutCalls = false;
171176
}
172-
this.keepaliveIntervalId = setTimeout(() => {}, 0);
173-
clearTimeout(this.keepaliveIntervalId);
174177
if (this.keepaliveWithoutCalls) {
175-
this.startKeepalivePings();
178+
this.maybeStartKeepalivePingTimer();
176179
}
177180

178181
this.subchannelAddressString = subchannelAddressToString(subchannelAddress);
@@ -375,6 +378,14 @@ class Http2Transport implements Transport {
375378
this.disconnectListeners.push(listener);
376379
}
377380

381+
private clearKeepaliveTimer() {
382+
if (!this.keepaliveTimerId) {
383+
return;
384+
}
385+
clearTimeout(this.keepaliveTimerId);
386+
this.keepaliveTimerId = null;
387+
}
388+
378389
private clearKeepaliveTimeout() {
379390
if (!this.keepaliveTimeoutId) {
380391
return;
@@ -383,7 +394,16 @@ class Http2Transport implements Transport {
383394
this.keepaliveTimeoutId = null;
384395
}
385396

386-
private sendPing() {
397+
private canSendPing() {
398+
return this.keepaliveTimeMs > 0 && (this.keepaliveWithoutCalls || this.activeCalls.size > 0);
399+
}
400+
401+
private maybeSendPing() {
402+
this.clearKeepaliveTimer();
403+
if (!this.canSendPing()) {
404+
this.pendingSendKeepalivePing = true;
405+
return;
406+
}
387407
if (this.channelzEnabled) {
388408
this.keepalivesSent += 1;
389409
}
@@ -402,6 +422,7 @@ class Http2Transport implements Transport {
402422
(err: Error | null, duration: number, payload: Buffer) => {
403423
this.keepaliveTrace('Received ping response');
404424
this.clearKeepaliveTimeout();
425+
this.maybeStartKeepalivePingTimer();
405426
}
406427
);
407428
} catch (e) {
@@ -411,46 +432,52 @@ class Http2Transport implements Transport {
411432
}
412433
}
413434

414-
private startKeepalivePings() {
415-
if (this.keepaliveTimeMs < 0) {
435+
/**
436+
* Starts the keepalive ping timer if appropriate. If the timer already ran
437+
* out while there were no active requests, instead send a ping immediately.
438+
* If the ping timer is already running or a ping is currently in flight,
439+
* instead do nothing and wait for them to resolve.
440+
*/
441+
private maybeStartKeepalivePingTimer() {
442+
if (!this.canSendPing()) {
416443
return;
417444
}
418-
this.keepaliveIntervalId = setInterval(() => {
419-
this.sendPing();
420-
}, this.keepaliveTimeMs);
421-
this.keepaliveIntervalId.unref?.();
422-
/* Don't send a ping immediately because whatever caused us to start
423-
* sending pings should also involve some network activity. */
445+
if (this.pendingSendKeepalivePing) {
446+
this.pendingSendKeepalivePing = false;
447+
this.maybeSendPing();
448+
} else if (!this.keepaliveTimerId && !this.keepaliveTimeoutId) {
449+
this.keepaliveTrace('Starting keepalive timer for ' + this.keepaliveTimeMs + 'ms');
450+
this.keepaliveTimerId = setTimeout(() => {
451+
this.maybeSendPing();
452+
}, this.keepaliveTimeMs).unref?.();
453+
}
454+
/* Otherwise, there is already either a keepalive timer or a ping pending,
455+
* wait for those to resolve. */
424456
}
425457

426-
/**
427-
* Stop keepalive pings when terminating a connection. This discards the
428-
* outstanding ping timeout, so it should not be called if the same
429-
* connection will still be used.
430-
*/
431458
private stopKeepalivePings() {
432-
clearInterval(this.keepaliveIntervalId);
459+
if (this.keepaliveTimerId) {
460+
clearTimeout(this.keepaliveTimerId);
461+
this.keepaliveTimerId = null;
462+
}
433463
this.clearKeepaliveTimeout();
434464
}
435465

436466
private removeActiveCall(call: Http2SubchannelCall) {
437467
this.activeCalls.delete(call);
438468
if (this.activeCalls.size === 0) {
439469
this.session.unref();
440-
if (!this.keepaliveWithoutCalls) {
441-
this.stopKeepalivePings();
442-
}
443470
}
444471
}
445472

446473
private addActiveCall(call: Http2SubchannelCall) {
447-
if (this.activeCalls.size === 0) {
474+
this.activeCalls.add(call);
475+
if (this.activeCalls.size === 1) {
448476
this.session.ref();
449477
if (!this.keepaliveWithoutCalls) {
450-
this.startKeepalivePings();
478+
this.maybeStartKeepalivePingTimer();
451479
}
452480
}
453-
this.activeCalls.add(call);
454481
}
455482

456483
createCall(

0 commit comments

Comments
 (0)