I have a queue which stored on Redis lists. I’m trying to create async consumer for this queue. But couldn’t call async function inside loop. Its working like sync function when I call.
import asyncio
async def worker():
print("starting sleep")
await asyncio.sleep(2)
print("slept")
async def main():
while True:
await worker()
asyncio.run(main())
Here is a short and simple example of mine implemantation. I’m expecting to see ‘starting sleep’ messages until first ‘slept’ message, it means for 2 seconds.
2
Answers
main
is literallyawait
ing the completion ofworker
. Untilworker
is done,main
won’t progress.async
tasks don’t run in the background like in multithreading.What you want is to keep launching new workers without
await
ing each one of them. However, if you just keep doing this in a loop like this:then you will never see any output of those workers, since this is an endless loop which never gives anything else the chance to run. You’d need to “break” this loop in some way to allow workers to progress. Here’s an example of that:
This will produce the expected outcome:
The
await
insidemain
transfers control back to the event loop, which now has the chance to run the piled upworker
tasks, When those worker tasksawait
, they in turn transfer control back to the event loop, which will transfer it back to eithermain
or aworker
as theirawait
ed sleep completes.Note that this is only for illustration purposes; if and when you interrupt this program, you’ll see notices about unawaited tasks which haven’t completed. You should keep track of your tasks and
await
them all to completion at the end somewhere.Here is an example using
asyncio.wait
:It spawns all the workers together.