1

Here's a toy example to illustrate my question: Suppose I have a function get_all_foos() which calls get_one_foo() several times. Each call to get_one_foo() calls do_sql_query(), which actually retrieves one foo by calling await db_conn.fetch(<some sql>).

Which of my three functions should be marked async? Does it add overhead if I mark them all async?

My mental model is that calling a function with await adds some sort of scheduling overhead, and doesn't make sense if that function doesn't do any IO itself, it only calls other functions that eventually do IO. But my mental model still may be left over from threading frameworks, rather than coroutine frameworks.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Alex
  • 129
  • 4
  • In an asynchronous program, most functions should definitely be marked async. There are only a few exceptions... – 12944qwerty May 11 '21 at 12:29

1 Answers1

2

The answer to the question from the summary is "yes" - you do need async all the way down.

My mental model is that calling a function with await adds some sort of scheduling overhead, and doesn't make sense if that function doesn't do any IO itself, it only calls other functions that eventually do IO.

Fortunately this is not correct. A simple await doesn't (necessarily) do any scheduling - it doesn't even drop into the event loop unless the awaited function chooses to suspend. An await immediately starts executing the awaitee and is no greater performance hit than starting to execute a generator (which is how awaiting is implemented).

This can sometimes even be a problem because a code that awaits something that never suspends actually ends up blocking the event loop.

user4815162342
  • 141,790
  • 18
  • 296
  • 355