Reputation: 140758
With python 3.5 or later, is there any difference between directly applying await
to a future or task, and wrapping it with asyncio.wait_for
? The documentation is unclear on when it is appropriate to use wait_for
and I'm wondering if it's a vestige of the old generator-based library. The test program below appears to show no difference but that doesn't really prove anything.
import asyncio
async def task_one():
await asyncio.sleep(0.1)
return 1
async def task_two():
await asyncio.sleep(0.1)
return 2
async def test(loop):
t1 = loop.create_task(task_one())
t2 = loop.create_task(task_two())
print(repr(await t1))
print(repr(await asyncio.wait_for(t2, None)))
def main():
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(test(loop))
finally:
loop.close()
main()
Upvotes: 11
Views: 5680
Reputation: 12587
The wait_for
gives two more functionalities:
Your example:
await f1
await asyncio.wait_for(f1, None) # or simply asyncio.wait_for(f1)
besides an overhead of calling additional wrapper (wait_for), they're the same (https://github.com/python/cpython/blob/master/Lib/asyncio/tasks.py#L318).
Both awaits
will wait indefinitely for the results (or exception). In this case plain await
is more appropriate.
On the other hand if you provide timeout argument it will wait for the results with time constraint. And if it will take more than the timeout it will raise TimeoutError
and the future will be cancelled.
async def my_func():
await asyncio.sleep(10)
return 'OK'
# will wait 10s
await my_func()
# will wait only 5 seconds and then will raise TimeoutError
await asyncio.wait_for(my_func(), 5)
Another thing is the loop argument. In the most cases you shouldn't be bothered, the use case is limited: inject different loop for tests, run other loop ...
The problem with this parameter is, that all subsequent tasks/functions should also have that loop passed along...
More info https://github.com/python/asyncio/issues/362
Upvotes: 9
Reputation: 1138
Unfortunately the python documentation is a little bit unclear here, but if you have a look into the sources its pretty obvious:
In contrary to await
the coroutine asyncio.wait_for()
allows to wait only for a limited time until the future/task completes. If it does not complete within this time a concurrent.futures.TimeoutError
is raised.
This timeout can be specified as second parameter. In your sample code this timeout
parameter is None
which results in exactly the same functionality as directly applying await
/yield from
.
Upvotes: 5