Merge pull request #2516 from murgatroid99/v1.8.x_upmerge_again

Merge v1.8.x into master
This commit is contained in:
Michael Lumish 2023-07-24 15:54:15 -07:00 committed by GitHub
commit 867caad554
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 28 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@grpc/grpc-js", "name": "@grpc/grpc-js",
"version": "1.8.18", "version": "1.8.19",
"description": "gRPC Library for Node - pure JS implementation", "description": "gRPC Library for Node - pure JS implementation",
"homepage": "https://grpc.io/", "homepage": "https://grpc.io/",
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",

View File

@ -962,8 +962,8 @@ export class Http2ServerCallStream<
} }
getPeer(): string { getPeer(): string {
const socket = this.stream.session.socket; const socket = this.stream.session?.socket;
if (socket.remoteAddress) { if (socket?.remoteAddress) {
if (socket.remotePort) { if (socket.remotePort) {
return `${socket.remoteAddress}:${socket.remotePort}`; return `${socket.remoteAddress}:${socket.remotePort}`;
} else { } else {

View File

@ -108,7 +108,12 @@ class Http2Transport implements Transport {
/** /**
* Timer reference for timeout that indicates when to send the next ping * Timer reference for timeout that indicates when to send the next ping
*/ */
private keepaliveIntervalId: NodeJS.Timer; private keepaliveTimerId: NodeJS.Timer | null = null;
/**
* Indicates that the keepalive timer ran out while there were no active
* calls, and a ping should be sent the next time a call starts.
*/
private pendingSendKeepalivePing = false;
/** /**
* Timer reference tracking when the most recent ping will be considered lost * Timer reference tracking when the most recent ping will be considered lost
*/ */
@ -169,10 +174,8 @@ class Http2Transport implements Transport {
} else { } else {
this.keepaliveWithoutCalls = false; this.keepaliveWithoutCalls = false;
} }
this.keepaliveIntervalId = setTimeout(() => {}, 0);
clearTimeout(this.keepaliveIntervalId);
if (this.keepaliveWithoutCalls) { if (this.keepaliveWithoutCalls) {
this.startKeepalivePings(); this.maybeStartKeepalivePingTimer();
} }
this.subchannelAddressString = subchannelAddressToString(subchannelAddress); this.subchannelAddressString = subchannelAddressToString(subchannelAddress);
@ -375,6 +378,14 @@ class Http2Transport implements Transport {
this.disconnectListeners.push(listener); this.disconnectListeners.push(listener);
} }
private clearKeepaliveTimer() {
if (!this.keepaliveTimerId) {
return;
}
clearTimeout(this.keepaliveTimerId);
this.keepaliveTimerId = null;
}
private clearKeepaliveTimeout() { private clearKeepaliveTimeout() {
if (!this.keepaliveTimeoutId) { if (!this.keepaliveTimeoutId) {
return; return;
@ -383,7 +394,19 @@ class Http2Transport implements Transport {
this.keepaliveTimeoutId = null; this.keepaliveTimeoutId = null;
} }
private sendPing() { private canSendPing() {
return (
this.keepaliveTimeMs > 0 &&
(this.keepaliveWithoutCalls || this.activeCalls.size > 0)
);
}
private maybeSendPing() {
this.clearKeepaliveTimer();
if (!this.canSendPing()) {
this.pendingSendKeepalivePing = true;
return;
}
if (this.channelzEnabled) { if (this.channelzEnabled) {
this.keepalivesSent += 1; this.keepalivesSent += 1;
} }
@ -402,6 +425,7 @@ class Http2Transport implements Transport {
(err: Error | null, duration: number, payload: Buffer) => { (err: Error | null, duration: number, payload: Buffer) => {
this.keepaliveTrace('Received ping response'); this.keepaliveTrace('Received ping response');
this.clearKeepaliveTimeout(); this.clearKeepaliveTimeout();
this.maybeStartKeepalivePingTimer();
} }
); );
} catch (e) { } catch (e) {
@ -411,25 +435,36 @@ class Http2Transport implements Transport {
} }
} }
private startKeepalivePings() { /**
if (this.keepaliveTimeMs < 0) { * Starts the keepalive ping timer if appropriate. If the timer already ran
* out while there were no active requests, instead send a ping immediately.
* If the ping timer is already running or a ping is currently in flight,
* instead do nothing and wait for them to resolve.
*/
private maybeStartKeepalivePingTimer() {
if (!this.canSendPing()) {
return; return;
} }
this.keepaliveIntervalId = setInterval(() => { if (this.pendingSendKeepalivePing) {
this.sendPing(); this.pendingSendKeepalivePing = false;
}, this.keepaliveTimeMs); this.maybeSendPing();
this.keepaliveIntervalId.unref?.(); } else if (!this.keepaliveTimerId && !this.keepaliveTimeoutId) {
/* Don't send a ping immediately because whatever caused us to start this.keepaliveTrace(
* sending pings should also involve some network activity. */ 'Starting keepalive timer for ' + this.keepaliveTimeMs + 'ms'
);
this.keepaliveTimerId = setTimeout(() => {
this.maybeSendPing();
}, this.keepaliveTimeMs).unref?.();
}
/* Otherwise, there is already either a keepalive timer or a ping pending,
* wait for those to resolve. */
} }
/**
* Stop keepalive pings when terminating a connection. This discards the
* outstanding ping timeout, so it should not be called if the same
* connection will still be used.
*/
private stopKeepalivePings() { private stopKeepalivePings() {
clearInterval(this.keepaliveIntervalId); if (this.keepaliveTimerId) {
clearTimeout(this.keepaliveTimerId);
this.keepaliveTimerId = null;
}
this.clearKeepaliveTimeout(); this.clearKeepaliveTimeout();
} }
@ -437,20 +472,17 @@ class Http2Transport implements Transport {
this.activeCalls.delete(call); this.activeCalls.delete(call);
if (this.activeCalls.size === 0) { if (this.activeCalls.size === 0) {
this.session.unref(); this.session.unref();
if (!this.keepaliveWithoutCalls) {
this.stopKeepalivePings();
}
} }
} }
private addActiveCall(call: Http2SubchannelCall) { private addActiveCall(call: Http2SubchannelCall) {
if (this.activeCalls.size === 0) { this.activeCalls.add(call);
if (this.activeCalls.size === 1) {
this.session.ref(); this.session.ref();
if (!this.keepaliveWithoutCalls) { if (!this.keepaliveWithoutCalls) {
this.startKeepalivePings(); this.maybeStartKeepalivePingTimer();
} }
} }
this.activeCalls.add(call);
} }
createCall( createCall(