diff --git a/CHANGELOG.md b/CHANGELOG.md index 945784f06..a3d0e2e4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ Changelog ========= +### v0.5.5 -- 2023-03-20 + +Notable changes: + +* Tweaked timeouts for HTTP2 connections, in the hopes of working around an + apparent HTTP2-related memory leak in the Node core library. This is + [issue #42710](https://github.com/nodejs/node/issues/42710) in the Node repo. + ### v0.5.4 -- 2023-03-10 Notable changes: diff --git a/src/main-lactoserv/package.json b/src/main-lactoserv/package.json index 166f4ac93..308ccfd52 100644 --- a/src/main-lactoserv/package.json +++ b/src/main-lactoserv/package.json @@ -1,6 +1,6 @@ { "name": "@this/main-lactoserv", - "version": "0.5.4", + "version": "0.5.5", "type": "module", "private": true, "license": "Apache-2.0", diff --git a/src/network-protocol/private/Http2Wrangler.js b/src/network-protocol/private/Http2Wrangler.js index 271b0b2cb..a1c29cd68 100644 --- a/src/network-protocol/private/Http2Wrangler.js +++ b/src/network-protocol/private/Http2Wrangler.js @@ -52,11 +52,28 @@ export class Http2Wrangler extends TcpWrangler { }; // Express needs to be wrapped in order for it to use HTTP2. - this.#application = http2ExpressBridge(express); - this.#protocolServer = http2.createSecureServer(serverOptions); - + this.#application = http2ExpressBridge(express); this.#application.use('/', (req, res, next) => this.#tweakResponse(req, res, next)); + + this.#protocolServer = http2.createSecureServer(serverOptions); this.#protocolServer.on('session', (session) => this.#addSession(session)); + + // Explicitly set both an overall server timeout _and_ the server's default + // socket timeout, as doing these _might_ mitigate a memory leak as noted in + // . As of this writing, there + // _is_ a memory leak of some sort in this project, and the working + // hypothesis is that setting this timeout will suffice as a fix / + // workaround (depending on one's perspective). That said, the discussion + // in the bug in question is ambiguous -- does just one of these need to be + // set? -- and so maybe this is now overkill (or whatever). + this.#protocolServer.setTimeout(Http2Wrangler.#SERVER_TIMEOUT_MSEC); + this.#protocolServer.timeout = Http2Wrangler.#SOCKET_TIMEOUT_MSEC; + + // TODO: Either remove this entirely, if it turns out that the server + // timeout is useless (for us), or add something useful here. + this.#protocolServer.on('timeout', () => { + this.#logger?.serverTimeout(); + }); } /** @override */ @@ -232,9 +249,22 @@ export class Http2Wrangler extends TcpWrangler { */ static #STOP_GRACE_PERIOD_MSEC = 250; + /** + * @type {number} How long in msec to wait before considering a server + * "timed out." TODO: Figure out if this has any real meaning if one isn't + * actually doing anything when timeout occurs. + */ + static #SERVER_TIMEOUT_MSEC = 5 * 60 * 1000; // Five minutes. + /** * @type {number} How long in msec to wait for a session to have activity - * before telling it to close. + * before considering it "timed out" and telling it to close. + */ + static #SESSION_TIMEOUT_MSEC = 2 * 60 * 1000; // Two minutes. + + /** + * @type {number} How long in msec to wait before considering a socket + * "timed out." */ - static #SESSION_TIMEOUT_MSEC = 5 * 60 * 1000; // Five minutes. + static #SOCKET_TIMEOUT_MSEC = 1 * 60 * 1000; // One minute. }