fix: close http2 sessions on close server#6137
Conversation
|
Putting objects into a Map, is always screaming to check for a potential memory leak. Maps will hold a strong reference to the Object, even though the Object is asssumed as destroyed. As the Map keeps a reference to the Object, it wil not get garbage collected. Your close function is more a closeAll. You need to extend your eventHandler for session, so that the session listens on the close and other relevant events (error?, goaway?), and then you remove it from your sessionstore. Well i am currently walking and did not test So i did not test my assumption by instantiating a http2 server and connecting and disconnecting to the server, without closing the server itself and measure the memory. But this should be considered. |
This comment was marked as outdated.
This comment was marked as outdated.
|
Well, I modified your PR. Hope you are fine with that. |
|
Thanks for your comments! It was my first pr and I'll take all your notes under advisement |
|
@kostyak127 just so that you dont feel bad, that I presumably "took over" your PR, I want to clarify, that I really appreciate your contribution. I dont know your skill level regarding Javascript. I want you to know that we encourage you and others to contribute to the project. I personally dislike to remark problems when I have already the potential solution on my computer. It will result in a constant nit pick, about why the contributor did it not the way I expected it. So you would get the feeling that I nag you and you get potentially frustrated. Yeah, that potential memory leak regarding Sets and Maps (or Arrays and Objects) is something, you learn usually, when your server crashes from OOM :D or others point it out to you, like in this PR. If you want to learn more about this type of Memory leak, compare Map vs. WeakMap and Set vs. WeakSet. In short: Example: const a = []
function doSomething() {
const b = {}
}If you know C++, then you read the curly braces differently. From StackOverflow Javascript is not that much different. Variable If you modify the code as follows: const a = []
function doSomething() {
const b = {}
a.push(b)
}Then Back to this PR: You would not run into this issue, when you would have used a WeakMap/WeakSet. WeakMaps and WeakSets dont accept primitives but only Objects, because they are created especially to avoid MemoryLeaks. But from a WeakMap/WeakSet you can not retrieve the Objects you passed into it - they have no Anyway as you see, now the code is adding listeners to the created Http2Session. When the session is connecting, it will add itself to that Set. And if it closes, it will remove itself from the Set. Thus ensuring, that the strong reference is not existing when the connection was closed, and thus the garbage collector can free the memory of the closed Session. But there is still potential work for this PR. First of all, do we need to modify the documentation? And furthermore, the more important question, is the implementation really complete? E.g. if a Http2Session times out, emitting a Maybe it is necessary to read the code in nodejs sourcecode to figure this out. |
|
@Uzlopak Thank you very much for the explanations! I truly appreciate that you took the time to point out and explain the issues in my code. As for the current pull request, I would like to continue working on it and investigate when exactly sessions should be closed. I’m not sure if this should be added to the documentation, because the current documentation (https://fastify.dev/docs/v5.2.x/Reference/HTTP2/) doesn’t describe configuration parameters (for example: http2SessionTimeout). I think I could use your advice on this. I’m also not sure what the right approach is for this PR, since I’ll need some time to fully understand everything. Should I close it and continue the work in a new PR? |
|
I think this PR is a good base to continue. It has a working solution for the general problem. If somebody wants to implement a solution for the corresponding issue, this person wouldnt need to start from scratch. Also we have an anti cookie licking policy. |
|
Hi! While I was researching how to properly handle session events, I looked into the Node.js source code as well as related issues to find problems similar to the one in Fastify — and here’s what I found: A closed issue: nodejs/node#57611 I also verified that the issue does not reproduce on Node.js v24.0.0. Maybe it makes sense to close this PR and the related issue (#5716)? |
|
First of all: You did a good research. We know now, that node 24 does not have this issue. But we are supporting also node 20 and 22. So for those two we need fallback solutions. So we need to continue the work. |
|
Hi! I’ve done a bit of investigation into how certain events behave and also reviewed the Node.js documentation. Here’s what I found: 1. Session cleanup in Node.js (v24) source code The Node.js source code removes the session on socket.on('close') and during session.destroy(). 2. List of Http2Session events 'close', 'connect', 'error', 'frameError', 'goaway', 'localSettings', 'close' 'error' 'frameError'
Handler added: 'goaway'
However, I tested this and found that the session is only closed after the next request is received following a 'goaway'. You can verify this behavior in my test repo: Proposal: Add a handler for 'goaway' and delete the session when it occurs. 'timeout' Please let me know what you think about these suggestions. P.S. i need to think a bit about how to cover the parts of code (Resolved) |



Refs: #5716
Checklist
npm run testandnpm run benchmarkand the Code of conduct