fs: fix close listener leak in FileHandle streams - #64227
Conversation
b433fb3 to
c4a165a
Compare
Fixes: nodejs#64214 Signed-off-by: y1d7ng <y1d7ng@yeah.net>
Fixes: nodejs#64214 Signed-off-by: y1d7ng <y1d7ng@yeah.net>
| function cleanup() { | ||
| options.fd.removeListener('close', onclose); | ||
| options.fd[kUnref](); | ||
| } | ||
| stream.once('end', cleanup); | ||
| stream.once('finish', cleanup); | ||
| stream.once('error', cleanup); |
There was a problem hiding this comment.
@Y1D7NG should we removeListener for all 3 in cleanup, so we don't leave these hanging as well?
| function cleanup() { | |
| options.fd.removeListener('close', onclose); | |
| options.fd[kUnref](); | |
| } | |
| stream.once('end', cleanup); | |
| stream.once('finish', cleanup); | |
| stream.once('error', cleanup); | |
| function cleanup() { | |
| options.fd.removeListener('close', onclose); | |
| stream.removeListener('end', cleanup); | |
| stream.removeListener('finish', cleanup); | |
| stream.removeListener('error', cleanup); | |
| options.fd[kUnref](); | |
| } | |
| stream.once('end', cleanup); | |
| stream.once('finish', cleanup); | |
| stream.once('error', cleanup); |
There was a problem hiding this comment.
From what I'm aware of for similar functions, it's common practice to (intentionally) leave these listeners dangling on the stream and rely on normal garbage collection to tidy it all up in the end.
There was some discussion on this stuff in #35452. In this case, the duplex stuff doesn't apply so I'd personally say it doesn't need the special handling that was eventually added there.
There was a problem hiding this comment.
Thanks for bringing that, that's interesting. Unsure how to proceed then. @nodejs/streams is the current behavior as expected?
There was a problem hiding this comment.
to be clear: in my comment I'm only talking about the events on the stream (end/finish/error) - removing the close listener from the file descriptor (i.e. the purpose of this PR) is definitely necessary.
There was a problem hiding this comment.
There are 2 approvals and a green CI.
Could this PR be landed, or does it need clarification of the above comments first?
There was a problem hiding this comment.
My comments are non-blocking, although I don't see it hurting waiting extra time to get insights from the right team tho.
There was a problem hiding this comment.
I think the listeners can be left to normal garbage collection
There was a problem hiding this comment.
After waiting 7 days there haven't been any further comments, or any blocking objections, so adding to commit queue.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as resolved.
This comment was marked as resolved.
|
Landed in 8488e13 |
|
This is broken and should be reverted. Will unref the handle multiple times. |
That is very unfortunate π ! Would you want to initiate the revert? I'm not sure how best to handle this. |
|
I'll submit a revert PR, if the original approvers and @ronag would be so kind as to approve the revert as well. |
I can approve. But for future reference, that's why we should wait for the subject matter experts to also approve. Even if that means the PR taking its due time to be merged. |
|
My mistake for not waiting long enough. Very sorry! |
In all fairness, it waited 7 days as required π |
fix: #64214
When autoClose is false, FileHandle.createReadStream registers a close listener on the handle. That listener is not removed after the stream finishes normally, so creating streams repeatedly on the same handle accumulates listeners.
In importFd, when autoClose is false, remove that listener and perform the corresponding unref cleanup when the stream ends (on end for read streams, on finish for write streams) or on error.