-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Since v20.13.0 fetch() ing small files without reading their body delays process termination for 8 seconds #52909
Comments
I see connection timeout instead of hanging with You can see the same happen on import { request } from 'http'
request('http://cms6-sites.webhare.com/test-arnold/empty.docx', (response) => {
console.log(response)
response.resume()
}).end() |
Possibly. To exclude the issue with any servers I control (although I originally found the issue on localhost with a different server setup) I've also tested against external servers. It seems file size related. now with this code
These are the results I see now, where Fails means 'it downloads but the process never terminates' To confirm it's not my server:
To demonstrate it appears to be size related (all these docs are random data)
And it's not the file size per se but seems to have to do with the request decoding
As far as I can tell, docs < 80KB fail, > 160 KB work, and I can confirm this with a few random servers found in google. For me the exact cutoff point is somewhere between 91KB and 92KB but if it's network related, the exact cutoff might differ for others EDIT: now also tested from a Rocky 9 host at Linode, ie in a DC, which seems to cut out somewhere between 120KB and 160KB |
It is a bit different from my environment. The address I connected to for import { request as http } from 'http';
import { request as https } from 'https';
import { fetch } from 'undici';
const sites = [
'http://cms6-sites.webhare.com/test-arnold/empty.docx',
'http://cms6-sites.webhare.com/test-arnold/empty-80kb.docx',
'http://cms6-sites.webhare.com/test-arnold/empty-91kb.docx',
'http://cms6-sites.webhare.com/test-arnold/empty-92kb.docx',
'http://cms6-sites.webhare.com/test-arnold/empty-160kb.docx',
'https://www.mhlw.go.jp/content/11120000/000908344.docx',
'https://www.careers.govt.nz/assets/pages/cv-and-cover-letter-templates/Cover-letter-template.docx',
'https://www.euro-divers.com/wp-content/uploads/2020/05/scuba-diving-instructor-resume.docx'
]
for(const site of sites) {
_fetch(site)
.then(() => { console.log('fetch done: %s', site) })
.catch((err) => { console.log('fetch fail: %s', site) })
_request(site)
.then(() => { console.log('request done: %s', site) })
.catch((err) => { console.log('request fail: %s', site) })
}
function _fetch(href) {
return fetch (href)
}
function _request(href) {
return new Promise((resolve, reject) => {
const request = href.startsWith('https') ? https : http
request(href, (response) => {
resolve(response)
response.resume()
}).on('error', (err) => {
reject(err)
}).end()
})
} request done: https://www.mhlw.go.jp/content/11120000/000908344.docx
fetch done: https://www.mhlw.go.jp/content/11120000/000908344.docx
request done: https://www.euro-divers.com/wp-content/uploads/2020/05/scuba-diving-instructor-resume.docx
fetch done: https://www.euro-divers.com/wp-content/uploads/2020/05/scuba-diving-instructor-resume.docx
request done: https://www.careers.govt.nz/assets/pages/cv-and-cover-letter-templates/Cover-letter-template.docx
fetch done: https://www.careers.govt.nz/assets/pages/cv-and-cover-letter-templates/Cover-letter-template.docx
fetch fail: http://cms6-sites.webhare.com/test-arnold/empty.docx
fetch fail: http://cms6-sites.webhare.com/test-arnold/empty-80kb.docx
fetch fail: http://cms6-sites.webhare.com/test-arnold/empty-91kb.docx
fetch fail: http://cms6-sites.webhare.com/test-arnold/empty-92kb.docx
fetch fail: http://cms6-sites.webhare.com/test-arnold/empty-160kb.docx
request fail: http://cms6-sites.webhare.com/test-arnold/empty.docx
request fail: http://cms6-sites.webhare.com/test-arnold/empty-80kb.docx
request fail: http://cms6-sites.webhare.com/test-arnold/empty-92kb.docx
request fail: http://cms6-sites.webhare.com/test-arnold/empty-160kb.docx
request fail: http://cms6-sites.webhare.com/test-arnold/empty-91kb.docx |
The problem related to the auto select family attempt timeout. import { setDefaultAutoSelectFamilyAttemptTimeout } from 'net';
setDefaultAutoSelectFamilyAttemptTimeout(1000) cc @ShogunPanda |
I'm not seeing network timeouts. I always see the requests complete immediately (well at least < 300ms, I haven't properly measured it). My problem is the process is not terminating (apprently because of a lingering/leaking TCPSocketWrap object because that's what my CI reported, but I haven't yet built a testcase that would also pinpoint it) If you're seeing network timeouts that's a pity, because then you're not reproducing the issue I'm seeing. I see you're in Hong Kong and all the testserves I have easy acces to are in Western Europe, so latency may be a factor. If noone else chimes in to confirm or deny being able to reproduce the issue, I'll try to set up the files elsewhere |
Said too early, it will close in both case but need to wait for a bit long if using the built-in.
|
keep-alive might indeed be part of the issue, but that doesn't directly explain why the downloaded file size (or more likely: timing differences caused by file size) changes the behavior. The server doesn't change its keep-alive behavior on the size so I'd expect the process to either always terminate or always hang, but not depend on the downloaded size. Thanks for the pointer. If I go straight for undici:
the change: GHSA-9f24-jqhm-jfcw aha. backpressure is probably the keyword here, as that would be related to file sizes. The workaround is to consume the incoming body, which I indeed don't, but that being the workaround would suggest that I don't need to do that in 6.6.1. if I consume the body I don't see the timeout anymore, but I didn't care about the body. As undici 6.16.0 still show the same behavior, I'd probably better file a bug there first if this behavior is indeed intentional. thanks for your help and pointing me in the right direction PS: the process does terminate after 8 seconds, but for my use case that's an eternity :-) |
I posted the issue to undici here - nodejs/undici#3230 - but without them changing anything, it's now fixed in node 22 (And still broken in 20 and 21) I've run a bisect and as far as I can tell this commit to node 22 fixed the issue: 1abff07 |
Version
v20.13.0
Platform
Linux 33f5daf61896 6.4.16-linuxkit #1 SMP PREEMPT Thu Nov 16 10:49:20 UTC 2023 aarch64 GNU/Linux
Subsystem
No response
What steps will reproduce the bug?
The node process will not terminate after downloading the document
How often does it reproduce? Is there a required condition?
100%
What is the expected behavior? Why is that the expected behavior?
Process should terminate
What do you see instead?
Process does not terminate
Additional information
Edit: fixed version number where it still works, there is no 20.12.3, oops.
The text was updated successfully, but these errors were encountered: