-
Notifications
You must be signed in to change notification settings - Fork 30.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fetch with AbortController signal memory leak (still) #52203
Comments
Here are some background information. (It has nothing to do with the issue itself, but explains why I need I use const ac = new AbortController()
const timer = setTimeout(() => ac.abort(), ms)
// add other abort conditions
const resp = await fetch(url, {
signal: ac.signal,
}) Obviously, the timeout should be cleared when the request is done or aborted: function request() {
const ac = new AbortController()
const timer = setTimeout(() => ac.abort(), ms)
// add other abort conditions
ac.signal.addEventListener("abort", () => {
clearTimeout(timer)
})
const resp = await fetch(url, {
signal: ac.signal,
})
ac.abort()
return resp.body
} I thought this should be work, but it didn't. So there must be something in the stream that uses However, in the above case it never is. |
Consider using
That's how the spec is written: “If response’s body is non-null and is readable, then error response’s body with error.“ Source
I think that's not enough to claim for a memory leak, the spec doesn't require the JS engines to call the cleanup callback. See Notes on cleanup callbacks for more information. As said over there, using |
@aduh95 Thanks for your response and information.
I know, but my actual scenario is more complex and needs to accept another
I do not use My real point is:
|
Any chance you could produce a code sample that demonstrates the memory leak without using |
// `stop` event may be dispatched by user, which will terminate any ongoing requests.
const ee = new EventEmitter()
for (let i = 0; i < 1000; i++) {
const ac = new AbortController()
const listener = () => ac.abort()
ee.on('stop', listener) // memory leak here
await fetch(url, {
signal: ac.signal,
})
// ee.off('stop', listener) // we cannot do this, because it will destory the read stream
}
In the above case, the leak does not go directly from But as we do not know when an |
Can this be closed? |
latest undici fixes it, and it landed in Node.js v22. Will be backported. |
Version
20.11.0
Platform
Microsoft Windows NT 10.0.22631.0 x64
Subsystem
undici
What steps will reproduce the bug?
There was an issue #48478 with repoduction https://github.com/Robert-Schirmer/nodejs-mem-leak, and it is not reproducible.
However
AbortController
still leaks in terms ofFinalizationRegistry
:How often does it reproduce? Is there a required condition?
Always (with node 20.11.0 native
fetch
).What is the expected behavior? Why is that the expected behavior?
Expected output:
What do you see instead?
Actual output:
Additional information
No response
The text was updated successfully, but these errors were encountered: