-
-
Notifications
You must be signed in to change notification settings - Fork 35k
bpo-35424: emit ResourceWarning at multiprocessing.Pool destruction #10974
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2577,6 +2577,22 @@ def test_enter(self): | |
| pass | ||
| pool.join() | ||
|
|
||
| def test_resource_warning(self): | ||
| if self.TYPE == 'manager': | ||
| self.skipTest("test not applicable to manager") | ||
|
|
||
| pool = self.Pool(1) | ||
| pool.terminate() | ||
| pool.join() | ||
|
|
||
| # force state to RUN to emit ResourceWarning in __del__() | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yuck. Why can't you test the actual situation? (start a pool then delete it)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you don't cleanup properly a pool, bad things happens. You can leak processes and threads and it's not easy to write a test which wait properly until they complete. If the test doesn't wait until they complete, the test can be marked as ENV_CHANGED and the whole test suite fails on buildbots. Leaking threads/processes have side effects on following tests which cause random failures. There is a "coverage" job on Travis CI which runs the full test suite sequentially for example.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, there was a PR to clean up pools properly, but AFAIR you reverted it...
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I reverted https://bugs.python.org/issue34172 change because it introduced a backward incompatible change in stable branches. I also reverted the change in the master branch to open a more general discussion: https://mail.python.org/pipermail/python-dev/2018-December/155946.html The reverted change isn't magic: it doesn't fix all issues. Even with this fix, the destructor still doesn't join many threads and so regrtest will still complain. The .join() method has to be called explicitly to really make sure that a test doesn't leak resources. The reverted change had a test on "del pool" and this test caused issues on buildbots because it leaked resources (processes, threads). IMHO testing that the destructor calls terminate() deserves its own separated test. In this PR, the test is restricted to check that the destructor emits a ResourceWarning. Moreover, to come back to https://bugs.python.org/issue34172 maybe you haven't noticed, by this PR should also help https://bugs.python.org/issue34172 because the problematic example ("for x in multiprocessing.Pool().imap(int, ["4", "3"]): print(x)") should now emit a ResourceWarning (once the reference cycle will be broken again). It's better than nothing to warn developers that something is wrong :-) See also https://bugs.python.org/issue35378 ... Sorry for the disgression, but it seems like you asked for it :-)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you want me to change the test, or is it ok written like that, with the explanation in my previous comment?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough, let's keep it like that :-) |
||
| pool._state = multiprocessing.pool.RUN | ||
|
|
||
| with support.check_warnings(('unclosed running multiprocessing pool', | ||
| ResourceWarning)): | ||
| pool = None | ||
| support.gc_collect() | ||
|
|
||
|
|
||
| def raising(): | ||
| raise KeyError("key") | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| :class:`multiprocessing.Pool` destructor now emits :exc:`ResourceWarning` | ||
| if the pool is still running. |
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.
Shouldn't you freeze
RUNin the__del__parameters as well?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.
done