Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.1k
Implement asyncio.Task.__cancel_requested__#31313
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
The design follows EdgeDB monkey-patch. Speaking about public API, I can imagine an alternative design:
I believe the proposed design is cleaner; it doesn't allow What do you think? |
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 -- my concern here is that__cancel_requested__
is a rather unconventional API design. I would rather name it_cancel_requested
, which is in line with the other attributes,or if we want this to be a truly public API (not just something for private use byasyncio.TaskGroup
) make it a pair of methods,cancel_requested()
returning abool
andset_cancel_requested()
taking abool
.
@asvetlov I apologize, I didn't see your large comment with the alternative design before my own comment. This stuff is excruciating to understand (for me anyways, since I didn't write EdgeDb's TaskGroup :-) so I have to experiment some more. I will see if I can get the new TaskGroup to work with that, I will get back to you. |
@asvetlov I cannot get this to work. Here's what I did. (1) Implement
(2) In taskgroups.py: Disable task patching in taskgroups.py; delete the assignment (of False) to
(3) Disable the C accellerator at the top of
Now when I run
I get failures in Can you repro this? Can you explain or fix it? |
I think I understand the cause of the failure now (not sure this will lead to a fix yet). Test 15 has a try/except in the body of the async with TaskGroup() block, where in the try block it awaits a long sleep (which will be cancelled from the outside after 0.1 second), and the except catches CancelledError and then sleeps some more (0.5s) before re-raising it. During this second sleep a subtask crashes (0.3s into the test). The desired behavior here is that the sleep in the except block isnot cancelled when the subtask crashes, and the sleep(0.5) is allowed to finish after which things reach (Test 16 is a variation where there's another task wrapping the whole business -- the outermost task is cancelled, and this is expected to be propagated into the nested task.) Because the initial cancellation of the parent task happens from the outside, it is essential that its I did find that none of the tests fail if I replace the line That's as far as I got. If we're going to design a public API for this, it would have to be a flag on tasks that is set when the task is cancelled, and which then stays set for the duration. We could add an API to reset the flag, which could be used by a task that catches cancellation and decides to ignore it (rather than just taking its time to clean up, like tests 15 and 16). Until the flag is cleared, further efforts to cancel the task are ignored. |
@asvetlov I would like to make progress on this. Mind if I just incorporate my version into the TaskGroup PR? My proposal is the following:
(@agronholm I think this may solve your problem too.) |
This means we no longer have to monkey-patch the parent task.It does introduce new semantics for task cancellation:When a task is cancelled, further attempts to cancel ithave *no* effect unless the task calls self.uncancel().Borrowed frompythonGH-31313 by@asvetlov.
Thanks,@gvanrossum |
Add
__cancel_requested__
property as discussed in#31270.cancel()
returnsFalse
is the task was previously cancelled already.No test is failing during the
cancel()
behavior change.