node version 18.16
- adding a listener to abortcontroller signal in isolation gets GC'd without removing, no leak
- both
node-fetchandglobal.fetchdo not appear to retain request bodies - both
node-fetchandglobal.fetchdo not appear to retain AbortController's associated with signals at request time node-fetchdoes not appear to retain the signal associated with a request beyond the lifecycle of the requestglobal.fetchDOES maintain a reference to the signal beyond request time (memory leak)global.fetchbut invoking.abort()does not appear to retain a reference to signal, even if invoked after a response is received
HTTP Request cancellation behaves differently depending on the lifecycle of request, the specific library used, and the stream read methods employed.
| node-fetch | global.fetch | |
|---|---|---|
| AbortController | ✅ Client ✅ Server | ✅ Client ✅ Server |
| node-fetch | global.fetch | |
|---|---|---|
| AbortController | 🤡^1 Client ❌ Server | ❌ Client ❌ Server |
| stream.destroy | 🤡^1 Client ❌ Server | N/A |
| request.destroy() (monkeypatch) | ✅ Client ✅ Server | N/A |
| stream.getReader().cancel | N/A | ✅^2 Client ✅ Server |
^1 = access to the response errors / stops but the underlying request continues to download the response
^2 = cancel(reason) does not throw an error, it resolves reader.read() with {value: undefined, done: true}