Skip to content
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

fix: 🐛 fix stuck in http request #81

Open
wants to merge 24 commits into
base: main
Choose a base branch
from

Conversation

binsee
Copy link

@binsee binsee commented Feb 2, 2023

Fixes: #80

src/misc.ts Outdated Show resolved Hide resolved
@hcfw007
Copy link
Contributor

hcfw007 commented Feb 2, 2023

Also I have done a little test

    stream
            .on('abort', console.log)
            .on('connect', console.log)
            .on('continue', console.log)
            .on('information', console.log)
            .on('response', console.log)
            .on('socket', console.log)
            .on('timeout', console.log)
            .on('upgrade', console.log)
            .on('close', console.log)
            .on('drain', console.log)
            .on('error', console.log)
            .on('finish', console.log)
            .on('pipe', console.log)
            .on('unpipe', console.log)

none of this were fired when network disconnected

@binsee
Copy link
Author

binsee commented Feb 2, 2023

See #80 for updated results

Copy link
Owner

@huan huan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking about we need an automation unit test for guarding this problem automatically.

src/file-box.ts Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
src/file-box.ts Show resolved Hide resolved
src/file-box.ts Outdated Show resolved Hide resolved
src/misc.ts Outdated Show resolved Hide resolved
src/misc.ts Outdated Show resolved Hide resolved
tests/network-timeout.spec.ts Outdated Show resolved Hide resolved
@binsee
Copy link
Author

binsee commented Feb 8, 2023

@huan
I updated the test. And made some modifications with reference to the nodejs code, it should work fine now.
However, I still think 60 seconds is too long and 5~10 seconds is perfectly sufficient. Too long a timeout and it will just wait in vain and throw an error.
This can be learned from should not timeout and should timeout in the test.

image
image

@huan
Copy link
Owner

huan commented Feb 10, 2023

https://betterstack.com/community/guides/scaling-nodejs/nodejs-timeouts/

In browsers, fetch() usually times out after a set period of time which varies amongst browsers. For example, in Firefox this timeout is set to 90 seconds by default, but in Chromium, it is 300 seconds.

@binsee
Copy link
Author

binsee commented Feb 12, 2023

Ok, I don't think there is enough testing in various scenarios now, and there is no need to set the default value too small.
In use, I can set the environment variable FILEBOX_HTTP_TIMEOUT as needed to achieve the effect I want, which is enough.
So are there any other questions now? Hope this can be merged sooner, to solve the problem I'm having.

@huan
Copy link
Owner

huan commented Feb 13, 2023

The latest problem is that the unit test clock is not mocked successfully: It will take a long time to finish the test, instead of seconds.

We have to figure out how to make the clock mock work before it can be merged.

@binsee
Copy link
Author

binsee commented Feb 13, 2023

I've spent a day researching this problem, but didn't find a solution. Therefore, I changed the test to run concurrently to reduce the overall time taken by this test.
Looks like looking at the source code of the nodejs project is required to find a clue, but I don't have enough time to do so right now.
Can we merge this first and then optimize the test time?

@binsee
Copy link
Author

binsee commented Feb 13, 2023

I investigated the source code of nodejs and found that the problem should be that socket.setTimeout uses the built-in setUnrefTimeout instead of the usual setTimeout.
Regardless of sion or jest, they only hook the common setTimeout, and there is no hook built-in setUnrefTimeout, so it cannot be mocked.

  • This is the socket's setTimeout call chain:

https://github.com/nodejs/node/blob/v16.x/lib/_http_client.js#L926-L952

https://github.com/nodejs/node/blob/v16.x/lib/net.js#L533

https://github.com/nodejs/node/blob/v16.x/lib/net.js#L74-L85

https://github.com/nodejs/node/blob/v16.x/lib/net.js#L237-L265

https://github.com/nodejs/node/blob/v16.x/lib/internal/timers.js#L372-L380

  • This is the general setTimeout:

https://github.com/nodejs/node/blob/v16.x/lib/timers.js#L140-L168

@huan
Copy link
Owner

huan commented Feb 13, 2023

You do not have to keep convincing me that this is impossible, as I believe everything should be testable.

Let me try to figure it out myself later.

Thanks.

@binsee
Copy link
Author

binsee commented Feb 16, 2023

Have you found any good solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Network failure can cause the program to be stuck in httpStream
3 participants