Tune fetch for improved connection management #1532
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hi @dgreif,
This PR is an attempt to address the native fetch/undici issues that were causing http requests to stop. I can provide a hugely detailed analysis of the failure, but, suffice it to say, I believe it has to do with how undici uses keepalive and pool connections. There are quite a number of similar issues on the undici project page.
To work around this, the PR imports Agent from the undici package and creates a custom dispatcher with fewer max TCP connections and much longer keepalive. This makes native NodeJS fetch behave more like browser fetch implementations as well as other http client libs like got (the actual values used are the same as Firefox). This actually has a mostly positive impact for all users as it dramatically reduces the number of DNS lookups and TCP handshakes, since the HTTP connections are now long lived.
So far, I've had 4 users that were experiencing the issue test this patch, and success has been 100%. I've tried to keep the patch as minimal as possible, with only the absolute minimum changes required.
In theory, it should even be possible to do this without pulling in undici dependency as it is possible to modify the global dispatcher, but I had some challenges with that and it felt very hackish. However, if you believe this is better, I can pursue it.
Also, with a custom dispatcher it is possible to enable HTTP/2 via the
allowH2: true
option. I did test this, however, H2 support in Undici has some pretty ciritcal bugs that regularly caused the NodeJS process to crash (issues are open, hopefully fixed in the next Undici release). I'll monitor this for the future, but it doesn't seem stable for the time being.