asyncio: schedule a coroutine
Once you write a coroutine, you need three things to get it running: create it, obtain a loop and schedule coroutine's execution.
The first two steps are trivial:
import asyncio
import sys
async def indication(timeout):
while True:
print('.', end='')
sys.stdout.flush()
await asyncio.sleep(timeout)
async def sleep(t, indication_t): # steps
coro = indication(indication_t) # 1
loop = asyncio.get_event_loop() # 2
# ...
await asyncio.sleep(t)
loop = asyncio.get_event_loop()
loop.run_until_complete(sleep(5, 0.5))
The slightly trickier part is to schedule execution of a coroutine within an already running loop.
There are two different ways to achieve that: loop.create_task(coro)
and asyncio.ensure_future(coro, loop=loop)
.
Though they both work, they have pretty different semantic.
create_task
does precisely what we need: it schedules execution of a coroutine and returns a future that allows you to track the coroutine execution (likely by awaiting it).
That future is strictly speaking a task (asyncio.Task
), the particular type of futures that wrap a coroutine.
ensure_future(x)
just ensures that x
is a future or wrap it in one.
If x
is a coroutine, is uses create_task
for such wrapping, obviously scheduling x
.
The previous name for ensure_future
is async
; it was changed to respect the fact that async
is a keyword now.
import asyncio
import sys
async def indication(timeout):
while True:
print('.', end='')
sys.stdout.flush()
await asyncio.sleep(timeout)
async def sleep(t, indication_t):
coro = indication(indication_t)
loop = asyncio.get_event_loop()
# # Choose one:
# loop.create_task(coro)
# asyncio.ensure_future(coro)
await asyncio.sleep(t)
loop = asyncio.get_event_loop()
loop.run_until_complete(sleep(5, 0.5))
Guido explicitly recommends using create_task()
since its intent is more clear.