-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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: improve open handles detection #9532
Conversation
Looks like this causes a regression. Mind taking a look? |
Yeah, I mentioned it in the OP. Unsure how to deal with it |
300d5cc
to
c9c10e9
Compare
I think it might be best to keep the ones that are deleted, but mark them as closed - that way if some async thing that async started something that's hanging but itself is closed (like the server example that CI caught) would still be visible, although it'd be noisier in the output |
c9c10e9
to
9ade171
Compare
9ade171
to
01c19f5
Compare
@@ -1,5 +1,26 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
|
|||
exports[`deals with http servers and promises 1`] = ` | |||
Jest has detected the following 1 open handle potentially preventing Jest from exiting: | |||
Of them 1 was collected within 100ms of the tests completing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this probably isn't clear enough...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about:
Detected 3 open handles potentially preventing Jest from exiting:
1. <red>DNSCHANNEL (uncollected, potential leak)
2. <red>Timeout (uncollected, potential leak)
3. <yellow>TCPSERVERWRAP (collected 100ms after test run, potentially spawned other uncollected handles)</yellow>
4 | const server = http.createServer();
5 | await new Promise(resolve => {
> 6 | server.listen(resolve);
[optionally] There were no uncollected handles - this is unexpected if your tests do not exit cleanly.
Not sure about the "optional" part. Shouldn't it say something like "Collected handles shouldn't prevent Jest from closing. Try something else"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed that, since it's an improvement regardless
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about moving the "Of them 1 was collected..." below, so it separates collected from uncollected more obvoiusly?
Detected 6 open handles potentially preventing Jest from exiting:
...
1 of them was collected within 100ms after the test run completed:
...
I'm also not a fan of:
Jest has detected the following 1 open handle potentially preventing Jest from exiting
as it contains "Jest" twice.
This is shorter and gets to the point:
Detected 6 open handles potentially preventing Jest from exiting
packages/jest-core/src/runJest.ts
Outdated
onComplete?: (result: AggregatedResult) => void; | ||
outputStream: NodeJS.WriteStream; | ||
}; | ||
|
||
const processResults = ( | ||
const wait = promisify(setTimeout); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we move this into createOpenHandlesResult
so it doesn't affect all test runs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
affect how? this just creates a new function in the module scope
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, CI complains. Doesn't locally though...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is likely not an issue at al. The point is, if we can avoid calling something, for a regular user in this scenario, why not doing so. Even if it's a small thing, they like to add up.
Hmm, weird CI sees a bunch if stuff I don't see locally... |
6e27752
to
a0500ca
Compare
I would love to see this merged. Anything I can do to help here? |
@jmikrut would love help making CI green 🙂 Once green this is good to land. On CI there are different timers than on my local machine, so hard to make the tests stable. I can rebase this in the meantime |
c1e8f0e
to
a58d262
Compare
a58d262
to
dc23efd
Compare
|
dc23efd
to
0ee0a52
Compare
0ee0a52
to
935035a
Compare
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Summary
Our current implementation is often fooled by promises, and we lose track of stack traces across async boundaries, meaning https://github.com/facebook/jest/blob/481077b09b05dc659b1fbd9ecf34a6486425208d/packages/jest-core/src/collectHandles.ts#L14 returns false negatives.
This is a work project before and after this fix
I honestly don't know about the first one (it's a false positive), but the second one lead to us fixing upstream here: valery-barysok/session-file-store#84
Fixes #8554.
Test plan
This breaks the stack trace of the existing server test. We get our current trace from the
GETADDRINFOREQWRAP
event, but that's gone in favour ofTCPSERVERWRAP
by the time the test exits, which does not have a stack trace. Unsure how to best deal with it