python - asyncio catch TimeoutError in Task -
i have asyncio.task need cancel after amount of time. before cancelling, task needs cleanup. according docs, should able call task.cancel or asyncio.wait_for(coroutine, delay) , intercept asyncio.timeouterror in coroutine, following example not working. i've tried intercepting other errors, , calling task.cancel instead, neither have worked. misunderstanding how cancelling task works?
@asyncio.coroutine def totimeout(): try: = 0 while true: print("iteration ", i, "......"); += 1 yield asyncio.sleep(1) except asyncio.timeouterror: print("timed out") def main(): #... stuff yield asyncio.wait_for(totimeout(), 10) #... more stuff asyncio.get_event_loop().run_until_complete(main()) asyncio.get_event_loop().run_forever()
the documentation asyncio.wait_for specifies cancel underlying task, , raise timeouterror wait_for call itself:
returns result of future or coroutine. when timeout occurs, cancels task , raises
asyncio.timeouterror.
and correct task cancellation can indeed intercepted:
[
task.cancel] arrangescancellederrorthrown wrapped coroutine on next cycle through event loop. coroutine has chance clean or deny request usingtry/except/finally.
note docs specify cancellederror thrown coroutine, not timeouterror.
if make adjustment, things work way expect:
import asyncio @asyncio.coroutine def totimeout(): try: = 0 while true: print("iteration ", i, "......"); += 1 yield asyncio.sleep(1) except asyncio.cancellederror: print("timed out") def main(): #... stuff yield asyncio.wait_for(totimeout(), 3) #... more stuff asyncio.get_event_loop().run_until_complete(main()) output:
iteration 0 ...... iteration 1 ...... iteration 2 ...... timed out traceback (most recent call last): file "aio.py", line 18, in <module> asyncio.get_event_loop().run_until_complete(main()) file "/usr/lib/python3.4/asyncio/base_events.py", line 316, in run_until_complete return future.result() file "/usr/lib/python3.4/asyncio/futures.py", line 275, in result raise self._exception file "/usr/lib/python3.4/asyncio/tasks.py", line 238, in _step result = next(coro) file "aio.py", line 15, in main yield asyncio.wait_for(totimeout(), 3) file "/usr/lib/python3.4/asyncio/tasks.py", line 381, in wait_for raise futures.timeouterror() concurrent.futures._base.timeouterror as can see, 'timed out' gets printed before timeouterror raised wait_for.
Comments
Post a Comment