-
Notifications
You must be signed in to change notification settings - Fork 1.9k
fix #6624 can't start new thread #6653
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
Conversation
conda/common/io.py
Outdated
@@ -395,16 +395,43 @@ def backdown_thread_pool(max_workers=10): | |||
"""Tries to create an executor with max_workers, but will back down ultimately to a single | |||
thread of the OS decides you can't have more than one. | |||
""" | |||
from concurrent.futures import _base # These "_" imports are gross, but I don't think there's an alternative # NOQA | |||
from concurrent.futures.thread import _WorkItem |
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.
Need to make sure these imports are ok for python 3.4 and python 3.5. They obviously are for python 2.7 and 3.6.
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.
Confirmed ok for both py34 and py35.
conda/common/io.py
Outdated
|
||
class CondaThreadPoolExecutor(ThreadPoolExecutor): | ||
|
||
def submit(self, fn, *args, **kwargs): |
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 an exact reimplementation of the submit()
method on the parent class, except I've added try/except
around self._adjust_thread_count()
. Seems to me like this is the technically sound and correct solution. I don't have any independent references though, and I'm frustrated it was so dirty to implement.
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.
Maybe if you included a link to the exact lines you copied on github (as a comment in the source) it'd make it easy to see if it's changed indicating you need to update your modified version?
5b2f144
to
95f66bc
Compare
95f66bc
to
159645e
Compare
BTW, at the moment tests are running, but they've all passed previously. I force-pushed only to correct some cosmetic things in docstrings. |
return f | ||
|
||
|
||
as_completed = as_completed # anchored here for import by other modules |
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.
Why do we need this here, if it is imported anyway on the top?
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.
It's for flake8 so that we don't have an unused import.
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.
ahhh right... you can just do
as_completed
for that, no ?
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.
Ok ;-)
# RuntimeError: can't start new thread | ||
# See https://github.com/conda/conda/issues/6624 | ||
if len(self._threads) > 0: | ||
# It's ok to not be able to start new threads if we already have at least |
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.
Ok so this looks like it will prevent a lot of issues, but maybe we can be honest that it will still occur (less likely though).
Maybe we need to add some python minor/patch version check and add some warning if it is not using the version for which this is tested. Or we could vendor (as@kalefranz suggest) it if it is small enough. I am just worried we inadvertedly fail due to api changes?
Maybe we should vendor this as part of this PR already and avoid future issues?
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.
Maybe we should vendor this as part of this PR already and avoid future issues?
Much prefer that to some type of version checking. I'll vendor it in this PR if @mingwandroid agrees.
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.
Ok so this looks like it will prevent a lot of issues, but maybe we can be honest that it will still occur (less likely though).
Yeah, if no threads can be created at all, then we have further work to do. I don't want to handle that case though until we actually see evidence that it exists.
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've looked at code for concurrent.futures in all the various locations. I'd rather not vendor right now. We'll of course test conda with python 3.7 before it's released, and other future versions. We're running all the unit tests now for every built conda package as part of the meta.yaml recipe, and given that we build python-specific versions of conda (not noarch), I think that mitigates the concerns for why we'd vendor.
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.
Ok, makes sense
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.
LGTM, left some minor comments
After this PR is approved and merged, I think there's some refactoring in order for the |
Hi there, thank you for your contribution to Conda! This pull request has been automatically locked since it has not had recent activity after it was closed. Please open a new issue or pull request if needed. |
fix #6624
This PR removes the
backdown_thread_pool
context manager, and replaces it withThreadLimitedThreadPoolExecutor
. The original purpose ofbackdown_thread_pool
was to preventRuntimeError
s as shown in #6624, but the strategy failed to do so. After looking more atconcurrent.futures.ThreadPoolExecutor
, it seems the exception will only be thrown when a new thread is created, and that only happens after submitting the first task. Sobackdown_thread_pool
was wholly ineffective at its intended purpose.This PR has some ugly parts, things I complain about in comments. Specifically import and usage of "protected" attributes (names starting with
_
) fromconcurrent.futures
. That seems unavoidable though. The only solution there would be to vendor our ownconcurrent.futures
. I'm indifferent on whether we want to do that or not.I'd like to have two reviewers on this PR. Probably @mingwandroid since he's already taken a first pass at it, and also @goanpeca.