From 30fe86e95a35d48c8829d1b7c71e6143741ca2a1 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 24 Jul 2024 03:50:40 +0200 Subject: [PATCH] fix: Improve timeout handling during event loop lag Make timeouts behave more closer that what is expected during event loop lag. --- lib/core/symbols.js | 1 + lib/dispatcher/client-h1.js | 9 ++++++++- lib/util/timers.js | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/core/symbols.js b/lib/core/symbols.js index 1c3732620b1..b4ab05bdcc2 100644 --- a/lib/core/symbols.js +++ b/lib/core/symbols.js @@ -11,6 +11,7 @@ module.exports = { kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), + kKeepAliveDeadline: Symbol('keep alive deadline'), kKeepAliveTimeoutValue: Symbol('keep alive timeout'), kKeepAlive: Symbol('keep alive'), kHeadersTimeout: Symbol('headers timeout'), diff --git a/lib/dispatcher/client-h1.js b/lib/dispatcher/client-h1.js index 2f1c96724d3..808a6290813 100644 --- a/lib/dispatcher/client-h1.js +++ b/lib/dispatcher/client-h1.js @@ -49,7 +49,8 @@ const { kMaxResponseSize, kOnError, kResume, - kHTTPContext + kHTTPContext, + kKeepAliveDeadline } = require('../core/symbols.js') const constants = require('../llhttp/constants.js') @@ -644,6 +645,7 @@ async function connectH1 (client, socket) { socket[kReset] = false socket[kBlocking] = false socket[kParser] = new Parser(client, socket, llhttpInstance) + socket[kKeepAliveDeadline] = 0 addListener(socket, 'error', function (err) { const parser = this[kParser] @@ -805,6 +807,7 @@ function resumeH1 (client) { if (client[kSize] === 0) { if (socket[kParser].timeoutType !== TIMEOUT_IDLE) { socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_IDLE) + socket[kKeepAliveDeadline] = Date.now() + client[kKeepAliveTimeoutValue] } } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { @@ -815,6 +818,10 @@ function resumeH1 (client) { socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS) } } + + if (socket[kKeepAliveDeadline] && socket[kKeepAliveDeadline] > Date.now()) { + util.destroy(socket, new InformationalError('socket idle timeout')) + } } } diff --git a/lib/util/timers.js b/lib/util/timers.js index d0091cc15f7..fa56be8b10e 100644 --- a/lib/util/timers.js +++ b/lib/util/timers.js @@ -2,13 +2,13 @@ const TICK_MS = 499 -let fastNow = Date.now() +let fastNow = 0 let fastNowTimeout const fastTimers = [] function onTimeout () { - fastNow = Date.now() + fastNow += TICK_MS let len = fastTimers.length let idx = 0