-
-
Notifications
You must be signed in to change notification settings - Fork 353
Implement capacity limitation for run_in_worker_thread #181
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
Codecov Report
@@ Coverage Diff @@
## master #181 +/- ##
==========================================
+ Coverage 99.06% 99.11% +0.05%
==========================================
Files 63 63
Lines 8420 8745 +325
Branches 609 629 +20
==========================================
+ Hits 8341 8668 +327
+ Misses 62 61 -1
+ Partials 17 16 -1
Continue to review full report at Codecov.
|
- New synchronization primitive: CapacityLimiter. Like a Semaphore but more specialized. See python-triogh-182 for rationale. - Add limiter= argument to run_in_worker_thread, that allows one to correctly (modulo python-trio#6 (comment)) control the number of active threads. - Added new function current_default_worker_thread_limiter(), which creates or returns a run-local CapacityLimiter, and made run_in_worker_thread use it by default when no other limiter= is given. Closes: python-triogh-10, python-triogh-57, python-triogh-156
I just pushed a new, much-expanded version of this that I think finishes solving the basic don't-run-too-many-threads-at-once problem, and I think it's ready for review if anyone wants to take a look. |
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.
Looks good overall, and probably more useful than the old version!
trio/_sync.py
Outdated
|
||
""" | ||
if borrower in self._borrowers: | ||
raise RuntimeError( |
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 this also be in the docstring?
trio/_threads.py
Outdated
def report_back_in_trio_thread_fn(result): | ||
print("in trio thread", result) | ||
def do_release_then_return_result(): | ||
print("asdF") |
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.
;)
@kyrias: Addressed those issues, and also added some docs and a few more tests. Let's see what Travis makes of this. The last run where everything froze on PyPy makes me very nervous. I can't reproduce it locally, but it seems too much too be a coincidence that both PyPy runs froze inside the thread tests on a PR dealing with the thread code... |
Welp, this appears to be a PyPy bug: https://bitbucket.org/pypy/pypy/issues/2591/closed-over-variable-updates-made-in-one I think we might need to drop PyPy support in our CI until this gets fixed. But for now I'm going to bed, and we'll see if @arigo has magically fixed it by the time I wake up :-) |
You can set it in an allow_faillure section in travis.ci. it still tests
but does not mark the GitHub status a red.
…On Jun 22, 2017 11:35, "Nathaniel J. Smith" ***@***.***> wrote:
Welp, this appears to be a PyPy bug: https://bitbucket.org/pypy/
pypy/issues/2591/closed-over-variable-updates-made-in-one
I think we might need to drop PyPy support in our CI until this gets
fixed. But for now I'm going to bed, and we'll see if @arigo
<https://github.com/arigo> has magically fixed it by the time I wake up
:-)
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#181 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAUezzBFYrmX8z2iXUovwHQWTyRinwRVks5sGjVggaJpZM4NpEOK>
.
|
This is bad. The test is totally valid, and we should be running it on PyPy. But it's hitting this PyPy bug: https://bitbucket.org/pypy/pypy/issues/2591/ This commit should be reverted after PyPy fixes that bug.
I just pushed a commit that skips the test for now on PyPy. I'm not super happy about this, because the test is valid and important. But this is an important feature that I don't want to get blocked by PyPy, and this has a few advantages over
|
Here's an exciting plot twist: the pypy bug where local variable assignments can just disappear, also affects all versions of CPython, probably back to 2.1 when closures were introduced! bpo-30744 It just happens that we don't trigger it because one of the required conditions is the presence of a Python-level tracing function, which on PyPy is provided by coverage.py, but on CPython coverage.py has a C accelerator module. |
Basically using nonlocal and threads together is super dangerous. - There was a weird/harmless one in _await_in_trio_thread, which caused me to clean up this code a bit. (It's better to use disable_ki_protection as a real decorator, in case it switches to mutating its argument in the future...) - Since test_run_in_worker_thread_limiter is actually doing something that's dangerous on both CPython and PyPy and the upstream fix is not obvious, let's just avoid nonlocal entirely.
def unprotected_fn(): | ||
return fn(*args) | ||
res = _core.Result.capture(unprotected_fn) | ||
print(res) |
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 wonder if it would make sense to add some off-by-default logging to various parts of trio, hooking into the logging module or somesuch. Might help with debugging things in general.
Wowza, that's pretty nasty behavior indeed. AFAICT the code does look sane at least, though I haven't actually played with it yet. |
I'm going to call that a review and merge this. This has been way more of a roller coaster than I expected and I want to get it landed before another surprise pops up :-). (Note for posterity: since it turns out that the test that broke PyPy is also fragile on all versions of CPython, I rewrote it to avoid using |
You can pass a Semaphore here to avoid overwhelming the system with
too many simultaneous threads.