Repository navigation
http2: clear the session timeout before marking it destroyed - #66886
nodejs-github-bot merged 2 commits into
Conversation
|
Review requested:
|
|
Welcome to Node.js, and thank you for your first contribution! Before review, please take a moment to read:
Please make sure every commit is signed off. For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal. Caution AgentScan found account activity patterns that may be consistent with automation. This is a heuristic, not proof that this pull request was opened by an agent or violates policy. AI-assisted contributions are permitted, but automated tooling must not open pull requests without advance approval, and contributors must personally understand, test, verify, and take responsibility for every submitted change. See the AgentScan analysis, AI use policy, and automation policy for additional context. |
|
Thanks for picking this up so quickly — the reordering is exactly what I had in mind. One suggestion for the test: it only covers a graceful close ( Checked on v26.12.1 (unpatched): with the raw socket destroyed, the server session closes with no 'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const assert = require('assert');
const http2 = require('http2');
const net = require('net');
// Same as test-http2-session-timeout-cleared-on-close.js, but the client's
// TCP socket is destroyed without sending GOAWAY.
const server = http2.createServer();
server.setTimeout(30_000, common.mustNotCall());
server.on('session', common.mustCall((session) => {
session.on('goaway', common.mustNotCall());
session.on('close', common.mustCall(() => {
assert.strictEqual(session.timeout, 0);
server.close();
}));
}));
server.on('stream', common.mustCall((stream) => {
stream.respond({ ':status': 200 });
stream.end('ok');
}));
server.listen(0, common.mustCall(() => {
let socket;
const client = http2.connect(`http://localhost:${server.address().port}`, {
createConnection: (url) => (socket = net.connect(url.port, url.hostname)),
});
client.on('error', () => {});
const req = client.request();
req.on('error', () => {});
req.resume();
req.on('end', common.mustCall(() => socket.destroy()));
})); |
|
Thanks — added |
This comment was marked as resolved.
This comment was marked as resolved.
closeSession() set SESSION_FLAGS_DESTROYED and then called session.setTimeout(0). setStreamTimeout() returns early when the session is destroyed, so the idle timer stayed armed and retained the session until the server timeout fired. Clear the timeout and remove its listeners before setting the destroyed flag. Fixes: nodejs#66885 Signed-off-by: huang <13165998033@163.com>
62afdff to
870c84c
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #66886 +/- ##
==========================================
+ Coverage 90.49% 90.65% +0.15%
==========================================
Files 797 797
Lines 278362 278485 +123
Branches 53484 53554 +70
==========================================
+ Hits 251908 252454 +546
+ Misses 16822 16386 -436
- Partials 9632 9645 +13
🚀 New features to boost your workflow:
|
The existing test only covers a graceful close, where the client sends GOAWAY. Destroy the client's TCP socket instead, so the server closes the session through socketOnClose() -> closeSession() directly, and no 'goaway' event fires. Signed-off-by: huang <13165998033@163.com>
870c84c to
50fff4b
Compare
|
Thanks for taking a look. The first commit's body exceeded 72 columns and was flagged by |
|
Landed in 663f666 |
closeSession()setSESSION_FLAGS_DESTROYEDand then calledsession.setTimeout(0).setStreamTimeout()returns early when the session is destroyed, so the idle timer stayed armed and retained the session until the server timeout fired.Clear the timeout and remove its listeners before setting the destroyed flag.
Fixes: #66885
Test:
test/parallel/test-http2-session-timeout-cleared-on-close.jsassertssession.timeout === 0after close. It fails on current main (actual: 30000, expected: 0) and passes with the reorder.I verified the behavior against the installed Node v24.14.0 with an emulated patch (the repo's
lib/needs a full build to run in-tree); the test itself was run with that patch.