1

Let say I have publisher publishing messages and a consumer which consumes it and call a database save method so which one should i use
await save(obj)
or
asyncio.create_task(save(obj))
and why ?

Prinz Piuz
  • 69
  • 9

1 Answers1

2

I don't know which one is the correct in your situation. Too little information. The differences are:

Await a coroutine:

....
result = await save(obj)
...

This will wait until save finishes before execution will continue with the next statement. In that time other tasks may run. Finally the value that save returns will be stored to result. Of course, you don't have to store the value, if you don't care. If an exception in save occurs, it will be propagated to the await statement and can (or should) be handled there.


Spawn a task:

...
task = asyncio.create_task(save(obj))
...

This will create a task and immediately continue with the next statement. A new task is not started immediately. It has a chance to run at the first await in the current task.

A task is "fire and forget". Unless you explicitly wait for its termination and retrieve the result, you will not receive the result, nor any exception that might have occurred. In case of an exception asyncio only prints a warning at the program end.


To select the right approach, you need to consider:

  1. awaited coroutine:
  • the current task cannot do anything else while it is busy running the save coroutine. Is it OK? In other words, if the application should react in some way in that time, some other tasks must be responsible for it.
  1. spawned task:
  • can save handle errors (e.g. recover, terminate the application if appropriate or at least write a warning to log)?
  • will the application wait for all spawned and running save tasks to finish their work before it terminates?
VPfB
  • 14,927
  • 6
  • 41
  • 75
  • how can we explain them based on thread and processes – Prinz Piuz Sep 06 '20 at 05:28
  • 1
    @PrinzPiuz That sounds like material for a separate question, but in the analogy with threads, `create_task()` is like `thread.start()`, and `await` is like `thread.join()`. The analogy is imperfect, though, because awaiting a coroutine without spawning it first (as in `await save()`) is close to a function call, but allowing suspensions. It doesn't have an equivalent in the threading world. – user4815162342 Sep 07 '20 at 07:19
  • 1
    @PrinzPiuz Just to make it clear, I'm not saying `await` is implemented using `thread.join()`, just that it's semantically similar. Asyncio is single-threaded and is _not_ based on multiple threads and processes. See answers to [this question](https://stackoverflow.com/questions/49005651/how-does-asyncio-actually-work) for details. – user4815162342 Sep 07 '20 at 13:57