-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
gh-131466: concurrent.futures.Executor.map
: avoid temporarily exceeding buffersize
while collecting the next result
#131467
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
base: main
Are you sure you want to change the base?
gh-131466: concurrent.futures.Executor.map
: avoid temporarily exceeding buffersize
while collecting the next result
#131467
Conversation
…llecting the next result
…Test.test_free_reference
concurrent.futures.Executor.map
: avoid temporarily exceeding buffersize
while collecting the next resultconcurrent.futures.Executor.map
: avoid temporarily exceeding buffersize
while collecting the next result
Lib/concurrent/futures/_base.py
Outdated
yield _result_or_cancel(fs.pop(), end_time - time.monotonic()) | ||
|
||
# Yield the awaited result | ||
yield fs.pop().result() |
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.
to be discussed: this could be replaced by a lighter yield fs.pop()._result
because the prior call to _result_or_cancel
guarantees that at this point the result is available.
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.
While I understand that we could possibly exceed buffersize
while collecting the next result, is there a real-word use case where it would really cause an issue? the reason is that we access to fs[-1]
and then do fs.pop()
.
I see that have a del fut
in _result_or_cancel()
but can you confirm that it's sufficient to not hold any reference to the yet-to-be-popped future?
Asking Gregory as well since he's the mp expert c: |
@picnixz sorry I re-asked your review because you made me realize that we actually don't need
I'm digging deeper into #95169 's context to check if I miss any non-tested scenario, especially regarding this:
|
yes, that's what I wanted to ask, but I'm not an expert here so i'll let you investigate first c: |
Context recap:
If we have:
What happens when calling
next(results)
:arg
frominterable
and put a task forfn(arg)
in the buffer-> During step 2. there is
buffersize + 1
buffered tasks.This PR swaps steps 1. and 2. so that
buffersize
is never exceeded, even duringnext
.concurrent.futures.Executor.map
temporarily exceeds itsbuffersize
while collecting the next result #131466