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: improve open handles detection #9532

Closed
wants to merge 12 commits into from

Conversation

SimenB
Copy link
Member

@SimenB SimenB commented Feb 7, 2020

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

image

image

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 of TCPSERVERWRAP by the time the test exits, which does not have a stack trace. Unsure how to best deal with it

@thymikee
Copy link
Collaborator

thymikee commented Feb 7, 2020

Looks like this causes a regression. Mind taking a look?

@SimenB
Copy link
Member Author

SimenB commented Feb 7, 2020

Yeah, I mentioned it in the OP. Unsure how to deal with it

@SimenB
Copy link
Member Author

SimenB commented Feb 19, 2020

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

@SimenB SimenB force-pushed the improve-open-handle-detection branch from c9c10e9 to 9ade171 Compare February 20, 2020 09:56
@SimenB SimenB force-pushed the improve-open-handle-detection branch from 9ade171 to 01c19f5 Compare February 20, 2020 10:06
@@ -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.
Copy link
Member Author

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...

Copy link
Collaborator

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"?

Copy link
Member Author

Choose a reason for hiding this comment

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

I like it!

Copy link
Member Author

Choose a reason for hiding this comment

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

image

thoughts? I kept the heading, since if there were many collected, it looked really noisy...

Copy link
Member Author

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

Like it

Copy link
Collaborator

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

@SimenB
Copy link
Member Author

SimenB commented Feb 20, 2020

My work project now looks like this, btw (the zlibs were there before as well):

image

So we keep the serverwrap from supertest that was previously removed, but we mark it as "collected". I think that makes sense 🙂 Hopefully people will look at the uncollected ones with stack trace first.

onComplete?: (result: AggregatedResult) => void;
outputStream: NodeJS.WriteStream;
};

const processResults = (
const wait = promisify(setTimeout);
Copy link
Collaborator

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?

Copy link
Member Author

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

Copy link
Member Author

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...

Copy link
Collaborator

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.

@SimenB
Copy link
Member Author

SimenB commented Feb 20, 2020

Hmm, weird CI sees a bunch if stuff I don't see locally...

@SimenB SimenB force-pushed the improve-open-handle-detection branch from 6e27752 to a0500ca Compare February 20, 2020 12:05
@jmikrut
Copy link

jmikrut commented Apr 16, 2020

I would love to see this merged. Anything I can do to help here?

@SimenB
Copy link
Member Author

SimenB commented Apr 16, 2020

@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

@SimenB SimenB force-pushed the improve-open-handle-detection branch from c1e8f0e to a58d262 Compare April 16, 2020 13:40
@SimenB SimenB force-pushed the improve-open-handle-detection branch from a58d262 to dc23efd Compare August 6, 2020 12:28
@SimenB
Copy link
Member Author

SimenB commented Aug 7, 2020

--runInBand in the tests seems to give same result locally as on CI - might help investigate at some point

@SimenB SimenB force-pushed the improve-open-handle-detection branch from dc23efd to 0ee0a52 Compare August 7, 2020 22:37
@github-actions
Copy link

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.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 20, 2021
@SimenB SimenB deleted the improve-open-handle-detection branch April 25, 2023 12:22
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Open handle when using http.Server.listen
4 participants