undici icon indicating copy to clipboard operation
undici copied to clipboard

How to disconnect after fetch?

Open daron4ever opened this issue 2 years ago • 3 comments

I would like to know how to close the connection after using fetch(URL) immediately?

daron4ever avatar Mar 29 '22 01:03 daron4ever

This is currently not possible. You can configure a global Agent that will do that.

mcollina avatar Mar 29 '22 15:03 mcollina

Use abortSignal?

jimmywarting avatar Jul 10 '22 21:07 jimmywarting

@jimmywarting it's not that simple. Undici maintains a persistent connection pool to the server with keep-alive sockets.

mcollina avatar Jul 11 '22 07:07 mcollina

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 🙂

metcoder95 avatar Oct 26 '22 11:10 metcoder95

I think using pipelining: 0 will always close the request

ronag avatar Oct 26 '22 11:10 ronag

I would do both.

mcollina avatar Oct 26 '22 11:10 mcollina

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 🙂

metcoder95 avatar Oct 26 '22 21:10 metcoder95

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.

silverwind avatar Dec 07 '22 13:12 silverwind

Can you upload a repro? What version of Node.js are you using?

mcollina avatar Dec 07 '22 15:12 mcollina

Node 19.1.0. Yes this should be possible to make a repro for, will try later.

silverwind avatar Dec 07 '22 20:12 silverwind