Signal behavior during garbage collection needs investigation but scope is contained
The issue reports that Request signals aren't properly aborted after garbage collection, contrary to expected behavior. It requires understanding of signal propagation and garbage collection in Node.js, but has a clear reproduction case. The maintainer discussion suggests this may involve spec compliance questions.
Passing a signal to Request() and aborting it does not cause the underlying request signal to be aborted after it's been garbage collected. This leads to issues where you want to listen on the request signal even after the request itself falls out of scope - e.g., the request is instantiated with an abort controller signal and downstream code is waiting for that signal to be aborted via request.signal.
Run the following using node --expose-gc main.js:
const ac = new AbortController();
ac.signal.addEventListener("abort", () => {
console.log("ac signal aborted");
});
const request = new Request("https://google.ca", { signal: ac.signal });
request.signal.addEventListener("abort", () => {
console.log("request signal aborted");
});
setTimeout(() => {
global.gc();
ac.abort();
}, 0);
ac signal aborted and request signal aborted should be logged to the console.
Instead, only ac signal aborted is logged.
Latest node and undici. Tried it in some older versions as well.
A few folks are running into this while trying to close event stream requests in the remix web framework. The underlying requests are never closed because the signal doesn't get aborted.
Claim this issue to let others know you're working on it. You'll earn 20 points when you complete it!