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

Account for time spent in garbage collection #3979

Open
wants to merge 27 commits into
base: master
Choose a base branch
from

Conversation

jobh
Copy link
Contributor

@jobh jobh commented May 10, 2024

Avoid flaky DeadlineExceeded due to garbage collection.

See #3975 (comment).

@jobh jobh requested a review from Zac-HD as a code owner May 10, 2024 11:11
Copy link
Member

@Zac-HD Zac-HD left a comment

Choose a reason for hiding this comment

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

OK, I really like this approach! You've already handled most of the tricky double-counting concerns too, so I have fewer nitpicks than I feared 🙂

hypothesis-python/src/hypothesis/statistics.py Outdated Show resolved Hide resolved
hypothesis-python/src/hypothesis/stateful.py Show resolved Hide resolved
hypothesis-python/src/hypothesis/core.py Outdated Show resolved Hide resolved
@jobh jobh force-pushed the gc-accounting branch 3 times, most recently from e452a0c to 3f79ceb Compare May 13, 2024 08:06
@jobh jobh force-pushed the gc-accounting branch 2 times, most recently from c434f20 to 2e5e9cf Compare May 13, 2024 14:31
@jobh

This comment was marked as outdated.

@@ -114,6 +114,9 @@ def __exit__(self, *args, **kwargs):
f"{sep}_pytest{sep}assertion{sep}rewrite.py",
f"{sep}_pytest{sep}_io{sep}saferepr.py",
f"{sep}pluggy{sep}_result.py",
# These are triggered by gc callbacks, for some reason
f"{sep}reprlib.py",
f"{sep}_pytest{sep}assertion{sep}util.py",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This makes the tests pass (fingers crossed), but is it just papering over something that should be fixed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note, the failures can be reproduced on master by adding

import gc; gc.callbacks.append(lambda *_: None)

at top level of conftest.py, so it's nothing to do with the other code changes.

Copy link
Member

Choose a reason for hiding this comment

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

Nah, this is totally fine - the whole purpose of this list is to suppress reports of unhelpful locations, and stdlib or pytest internals are almost always in that category. (at some point maybe we should generalize this further with an is_pytest_file helper?)

Copy link
Contributor Author

@jobh jobh May 15, 2024

Choose a reason for hiding this comment

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

Would you support something like this: jobh@5ddfd2e

It's just adding some glob wildcards

@jobh jobh force-pushed the gc-accounting branch 3 times, most recently from 8d23490 to e580dff Compare May 14, 2024 08:15
@jobh jobh force-pushed the gc-accounting branch 5 times, most recently from 1395d9d to 68e818a Compare May 14, 2024 10:34
@jobh
Copy link
Contributor Author

jobh commented May 14, 2024

All tests passed, finally. There were more complications than I expected, the two major ones are commented above.

The scrutineer part is probably just due to more variation in traces; which can be seen as a good thing, as the variation covers more of real-world usage (although some globbing would be nice to have in that list).

The recursion depth thing may or may not be a problem in practice, I just don't know. I set out to kill one source of flakiness, only to create another. Not happy with that one is ok actually.

Anyway: Ready for re-review :-)

@Zac-HD
Copy link
Member

Zac-HD commented May 14, 2024

(jumping on a flight to PyCon now, but the Scrutineer thing is not a problem, and I'll aim to review the unraisable problem later)

@jobh
Copy link
Contributor Author

jobh commented May 14, 2024

(jumping on a flight to PyCon now, but the Scrutineer thing is not a problem, and I'll aim to review the unraisable problem later)

Thanks @Zac-HD! Have fun at PyCon!

@Zac-HD
Copy link
Member

Zac-HD commented May 20, 2024

(just want to note that I haven't forgotten about this; it's just tricky enough that I need a dedicated chunk of time to think about it and make sure I've tested all the edge cases. thanks for your patience 🙏)

and also handle it in scrutineer trace, since that can happen.
Copy link
Member

@Zac-HD Zac-HD left a comment

Choose a reason for hiding this comment

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

Thanks @jobh, I've added a last test based on your repro and I think we're ready to merge!


Account for time spent in garbage collection during tests, to avoid
flaky DeadlineExceeded errors. Also fixes overcounting of stateful
run times, introduced in PR #3890.
Copy link
Member

Choose a reason for hiding this comment

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

For the changelog, refer to version numbers rather than PRs - the latter are much more meaningful for downstream users, even if we think in terms of pr references 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted! I will put some prose in the RELEASE example to this effect.

hypothesis-python/tests/conjecture/test_engine.py Outdated Show resolved Hide resolved
(``https://hypothesis.readthedocs.io/en/latest/<chapter>.html#<anchor>``)
be ``package.function``, or :func:`~package.function` to show ``function``.
- :class:`package.class` for link to classes (abbreviated as above).
- :issue:`issue-number` for referencing issues, :pr:`pr-number` for pull requests.
Copy link
Member

Choose a reason for hiding this comment

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

oops, we only support :pull: at the moment. Happy to either change the docs, or add an alias in conf.py.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will change the docs 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

but either I or Github is confused. I didn't see this comment (or several others) before now, but they are timestamped "last week". I'll have a look through again to make sure everything is covered!

Comment on lines 4 to 5
flaky `DeadlineExceeded` errors as seen in :issue:`3975`. Also fixes
overcounting of stateful run times resulting from :pr:`3890`.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
flaky `DeadlineExceeded` errors as seen in :issue:`3975`. Also fixes
overcounting of stateful run times resulting from :pr:`3890`.
flaky ``DeadlineExceeded`` errors as seen in :issue:`3975`.
Also fixes double-counting of runtime for stateful rules, towards overall test execution runtime,
a minor observability bug dating to :ref:`version 6.98.9 <v6.98.9>`.

@Zac-HD Zac-HD enabled auto-merge May 23, 2024 16:32
@Zac-HD Zac-HD disabled auto-merge May 23, 2024 17:10
@Zac-HD
Copy link
Member

Zac-HD commented May 23, 2024

Apparently GitHub didn't send my review correctly last week??? Sorry about that, I should have spotted it.

@jobh
Copy link
Contributor Author

jobh commented May 23, 2024

Aha, I guess the comments are batched up until the review is completed. No worries from my side, just a bit of extra work for you to fix the things I neved did 😁

@Zac-HD
Copy link
Member

Zac-HD commented May 23, 2024

I'm also somewhat concerned by the number of failures I'm seeing on e5a2390, which looked like a very small change - crashed worker on Windows and linux, this weird error on several builds, prints-on-healthcheck tests on several builds...

It looks like several of these would be fixable, but I'm wondering whether the benefits of measuring GC time are actually worth the fragility vs e.g. running gc.collect() before each 100th test execution.

@jobh
Copy link
Contributor Author

jobh commented May 23, 2024

It looks like several of these would be fixable, but I'm wondering whether the benefits of measuring GC time are actually worth the fragility vs e.g. running gc.collect() before each 100th test execution.

Yep. Let's wait a bit with this, and then when I have more time I'll try to understand what happens and why. The actual execution-time change seems so small, but sometimes it just doesn't work.

@jobh
Copy link
Contributor Author

jobh commented May 24, 2024

I think it's ok actually.

The NaN infects every timing result afterwards, which is why deadlines fail. That's fixable.

While I don't fully understand the crashes, I believe they are likely caused by memory exhaustion due to the new test's deep recursion inside gc. We need to do the recursion outside and then probe gc at each stack level, otherwise we're not testing the shallowest-level callback properly.

[edit: the test still crashes, even with no callback attached (i.e., no gc accounting)]

@jobh jobh force-pushed the gc-accounting branch 3 times, most recently from 2a943be to da3b950 Compare May 24, 2024 09:37
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.

None yet

2 participants