-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
gh-97696: DRAFT asyncio eager tasks factory prototype #101613
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
Closed
Closed
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
1ea845c
Copy GH-98137, make some changes, add benchmarking script, trying to …
itamaro de6d910
asyncio runner takes optional task factory arg
itamaro 56610e7
don't coro.send if the event loop is not running (yet)
itamaro 34082a7
modify async tree script to support eager factory
itamaro ce5beaf
don't over-count tasks that yield result immediately
itamaro 38d7b0b
handle task._source_traceback in eager task factory
itamaro 6afbaab
stop checking for eager factory in taskgroups
itamaro a6e68bc
refactor async tree benchmark to work with TaskGroup or gather depend…
itamaro 464bd49
restore C task
itamaro ac26ad6
yield_result -> coro_result
itamaro ae2dcf3
Support `coro_result` in Task C impl
itamaro 9794715
Merge branch 'main' into asyncio-eager-tasks-playground
itamaro 0b447b0
Address Dino's review comments
itamaro f2748e2
passthrough coro_result from custom constructor only if it is set
itamaro 61ac5d0
add != NULL assertion on step2 result
itamaro cbd14fb
Merge branch 'main' into asyncio-eager-tasks-playground
itamaro 3503337
fix result refcnting in task_step_handle_result_impl
itamaro 49c0e89
Add eager task factory tests
itamaro 8a5229a
cleanup eager task factory tests
itamaro d1e5fd1
add news blurb
itamaro 580fb1f
Merge branch 'main' into asyncio-eager-tasks-playground
itamaro 6284c41
apply patchcheck fixes in asyncio.tasks
itamaro 34123a7
regenerate clinic
itamaro File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
add != NULL assertion on step2 result
- Loading branch information
commit 61ac5d02ecb40acede6a35c70dc8fc9ab37ccefa
There are no files selected for viewing
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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 incref seems a little weird? The caller should be keeping this alive for the lifetime of the call, and if
task_step2_implwants to hold onto it then it seems it should do the inc ref.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 ran into refcnt assertions and adding this made them go away 😬 I don't have a stronger justification for doing it here, so I'll need to dig deeper
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.
from reading the code, I think the issue is on line 2911 in
task_step_handle_result_impl, where the result is handed off to the task and there's currently a comment that "no incref is necessary." That comment made sense whenresultwas fully a local variable oftask_step_impl, so it could just hand off its owned reference to the task. but now that code is wrong (or at least, is assumingtask_step_handle_result_implsteals the reference to itsresultargument, which isn't the typical/best approach.) So I think adding this incref is actually one "correct" option (as in, the refcounts all end up correct), but it's probably not the clearest / most maintainable option. The better option might be to add the incref down intask_step_handle_result_implwhere it gives a reference to the task, and then add a decref ofresultat the end oftask_step_implafter callingtask_step_handle_result_impl(sincetask_step_handle_result_implwill no longer be stealing that reference.)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.
good point, thanks @carljm !
tried moving the incref where you suggested and still ran into negative refcounts (in different cases though, like "different loop" test). it works if I incref right in the beginning of the function - we can go with that, or I can try make it more granular by chasing down all the branches that would need the incref the 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.
So currently the code in
task_step_handle_result_implwas written with the assumption that it owns its reference toresult. I didn't initially look down through its code far enough to see all the places that assumption manifests, but in addition to line 2911, there's also line 3004, and then below that there are a bunch of error exit cases that doPy_DECREF(result), which only makes sense under the assumption that the reference is owned.So the choices are either to incref it right away, so that the assumption made by the rest of the existing code continues to be true, or to modify the code so it increfs on line 2911 and 3004 (I think those are the only spots I see?) where it stores a new reference, and so it doesn't decref on all the various error exits at the end of the func.
The latter choice is more typical, because generally doing it more lazily results in fewer reference counting operations (i.e. in one of the error-exit cases, no refcount operations should be needed at all, but the "incref early" option means there's a pointless incref and then decref), and also because it's typically less error prone to future changes (instead of having to remember to decref
resulton every exit path that does nothing withresult, which is harder to remember precisely because you aren't doing anything withresult, you only have to incref on the paths where you actually do store a new reference toresult, which is pretty natural. But it does mean more changes to the current code.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.
thanks for the explanation! super helpful :)
the last commit I just pushed (adding 2 increfs and removing a bunch of decrefs) seems to be working!