Difference between await Coroutine and await Task

3.3k Views Asked by At

On FastAPI, I have an endpoint that calls get_1 or get_2 coroutine function below.

get_1 uses await redis.get(key)

get_2 uses await asyncio.ensure_future(redis.get(key))

Is there any difference between the 2 functions in terms of functionality and performance?

#redis.py

import asyncio
import aioredis

async def get_1(key):
   redis = aioredis.from_url("redis://localhost")
   value = await redis.get(key)
   return value

async def get_2(key):
   redis = aioredis.from_url("redis://localhost")
   value = await asyncio.ensure_future(redis.get(key))
   return value
1

There are 1 best solutions below

4
alex_noname On

First of all, to understand what exactly await does and how task differs from future, I recommend starting with this topic and, of course, official documentation.

As for your question, at first glance, the both expressions await coro() and await create_task(coro()) do the same thing. They start coroutine, wait for it to complete and return the result.

But there are a number of important difference:

  • The await coro() leads to direct call to the coroutine code without returning execution path to event loop. This issue was explained in this topic.
  • The await create_task(coro()) leads to wrapping the coroutine in a task, scheduling its execution in the event loop, returning execution path to event loop and then waiting for the result. In this case, before executing of the target coroutine(scheduled as a task) other already sheduled tasks can be executed. Usually, await is not used with create_task, to allow a spawned task to run in parallel, but sometimes it is needed, the example in the next paragraph
  • The await coro() executes the target coroutine within the current context of variables, and the await create_task(coro()) within the copy of the current context (more details in this topic).

Based on the above, most likely you want await coro(), leaving the second expression for more specific cases.