Message370164
I was searching for a way to "yield" from task/coroutinue back to the event loop (not yielding a value in terms of a generator) and not finding anything documented, I found this bug report and PR:
https://github.com/python/asyncio/issues/284
It states that asyncio.sleep(0) should cause the coroutine to send control back to the event loop without wastefully doing other work. That makes sense and a perfectly good way to do that.
And, the code appears to handle a value of <= 0 specifically: https://github.com/python/cpython/blob/3.8/Lib/asyncio/tasks.py#L632
However, using sleep(0) to yield back does not cause it to raise a CancelledError if the task has been cancelled as cancel()'s documentation indicates it should. But sleeping for anything >0 does (e.g. 0.001)
The below code snippet will demonstrate the problem:
TIA
----
import asyncio
import time
async def cancel_me():
print('cancel_me(): before sleep')
try:
while True:
print("doing some really intensive cpu stuff")
time.sleep(2)
# now I want to yield control back to the event loop in order to determine if we've been cancelled
await asyncio.sleep(0) # I'm expecting this to throw CancelledError, but it never does.. it DOES throw if the delay > 0 (e.g. 0.001)
except asyncio.CancelledError:
print('cancel_me(): cancelled!')
raise
async def main():
task = asyncio.create_task(cancel_me())
await asyncio.sleep(1)
task.cancel()
try:
await task
except asyncio.CancelledError:
print("main(): cancel_me is cancelled now")
asyncio.run(main()) |
|
Date |
User |
Action |
Args |
2020-05-28 05:36:59 | Davy Durham | set | recipients:
+ Davy Durham, asvetlov, yselivanov |
2020-05-28 05:36:59 | Davy Durham | set | messageid: <1590644219.7.0.394616254827.issue40800@roundup.psfhosted.org> |
2020-05-28 05:36:59 | Davy Durham | link | issue40800 messages |
2020-05-28 05:36:59 | Davy Durham | create | |
|