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
] arrangescancellederror
thrown 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