undici
undici copied to clipboard
How to disconnect after fetch?
I would like to know how to close the connection after using fetch(URL) immediately?
This is currently not possible. You can configure a global Agent that will do that.
Use abortSignal?
@jimmywarting it's not that simple. Undici maintains a persistent connection pool to the server with keep-alive sockets.
Hey! I've been taking a look into this one but have some doubts about the possible shape of the API to control this behavior.
My initial idea was to provide a new option property to the init
param of the fetch
function, that when true
it calls dispatcher.destroy()
after a fetch. Something like:
const result = await fetch('https://example.com', { autoClose: true });
// this results in a `dispatcher.destroy` getting called after the full body is consumed
// depending on the user's implementation
But it didn't seem too ergonomic as it adds a new prop outside of the fetch
spec and also makes the implementation to be fully aware of the body's consumption (if any) to properly start to destroy either the pool or standalone agent
.
The second option I have in mind is to add the autoClose
option directly to the agent
that allows the agent to self-destroy/close after any request.
Would like to hear your thoughts, so I can draft some proposal afterwards 🙂
I think using pipelining: 0 will always close the request
I would do both.
I think using pipelining: 0 will always close the request
That's true, but that's not always obvious (I think that is not present in the docs). I found myself quite a few times looking at why tap
finished the tests but was hanging at an open handle until I figured out/remembered that undici
was persisting the connection.
Having it more explicit can improve ergonomics, but also making it more explicit in the documentation will solve the issue. Not sure which one is better, to be honest, matter of tradeoffs maybe?
I would do both.
Sure, I'll work on PoC then 🙂
I have a odd case where the vitest
process keeps hanging randomly after fetch
was invoked (about 1 in 10 runs). I'm already passing pipelining: 0
but it seems to have no effect. Switching to node-fetch
resolves the issue. I have not yet tried dispatcher.destroy()
but it seems quiet unergonomic if that is necessary to allow the process to cleanly shut down without open handles.
Can you upload a repro? What version of Node.js are you using?
Node 19.1.0. Yes this should be possible to make a repro for, will try later.