FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-110205: Fix asyncio ThreadedChildWatcher._join_threads() by vstinner · Pull Request #110790 · python/cpython · GitHub

Repository navigation

gh-110205: Fix asyncio ThreadedChildWatcher._join_threads() - #110790

Closed
vstinner wants to merge 3 commits into
python:mainfrom
vstinner:asyncio_clear_watcher_threads
Closed

vstinner wants to merge 3 commits into
python:mainfrom
vstinner:asyncio_clear_watcher_threads

Conversation

vstinner commented Oct 13, 2023 •
edited by bedevere-app Bot
Loading

Copy link
Copy Markdown
Member

ThreadedChildWatcher._join_threads() now clears references to completed threads.

test_asyncio.utils.TestCase now calls _join_threads() of the watcher, uses SHORT_TIMEOUT to join a thread, and then raises an exception if there are still running threads.

Rename also ThreadedChildWatcher threads to add "asyncio-" prefix to the name.

ThreadedChildWatcher._join_threads() now clears references to
completed threads.

test_asyncio.utils.TestCase now calls _join_threads() of the watcher,
uses SHORT_TIMEOUT to join a thread, and then raises an exception if
there are still running threads.

Rename also ThreadedChildWatcher threads to add "asyncio-" prefix to
the name.

gvanrossum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Is there any advantage to using the internal API _join_threads() instead of the internal variable _threads? You could just add the timeout arg to the join() call in the existing test cleanup code.

Comment thread Lib/asyncio/unix_events.py Outdated
Comment on lines +1384 to +1385
self.threads = [thread for thread in list(self._threads.values())
if thread.is_alive() and not thread.daemon]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Why are you creating a new instance variable self.threads here? Did you intend to clean out completed threads from the dict self._threads?

vstinner Oct 13, 2023 •
edited
Loading

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I used the list comprehension above as an example, for me it looks easier to remove completed threads rather than having a regular list and removing items from the list.

The purpose of this line is to remove completed threads to save memory and to fix the dangling threads issue.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Do you mean that you prefer to not create a new list?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I modified my PR to use self.threads[:] = ..., so the self.threads list object is not replacd.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Do you mean that you prefer to not create a new list?

No I meant that the tests fail because self._threads is a dict, not a list.

Copy link
Copy Markdown
Member Author

Is there any advantage to using the internal API _join_threads() instead of the internal variable _threads?

It fix the issue related to the PR: dangling thread. The warning can be emitted when the Python object still exist, even if the thread is no longer running. I don't think that copy/paste the _join_threads() logic in the test is worth it.

Copy link
Copy Markdown
Member

Please take a break and read the comments and the code. There is no variable self.threads.

Copy link
Copy Markdown
Member Author

Please take a break and read the comments and the code. There is no variable self.threads.

Ah, I misunderstood your comment. I fixed the typo, the code now sets self._threads.

vstinner closed this Oct 13, 2023
vstinner deleted the asyncio_clear_watcher_threads branch October 13, 2023 17:53
Comment on lines +1384 to +1385
self._threads[:] = [thread for thread in list(self._threads.values())
if thread.is_alive() and not thread.daemon]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

As I was trying to let you see for yourself, self._threads is a dict, not a list. If you want to update it using a comprehension you can use something like this:

self._threads = {key: thread for key, thread in self._threads.items() if thread.daemon or thread.is_alive()}

Please test locally before merging.

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants


Back | FazBrowse Home | New Git URL