I am trying to create a RabbitMQ client based on aio-pika, as I need to handle messages asynchronously. This is the quick start code for asynchronous message handling: (see original code on the aio-pika site)
import asyncio
import aio_pika
async def process_message(
message: aio_pika.abc.AbstractIncomingMessage,
) -> None:
async with message.process():
print(message.body)
await asyncio.sleep(1)
async def main() -> None:
connection = await aio_pika.connect_robust(
"amqp://guest:[email protected]/",
)
queue_name = "test_queue"
# Creating channel
channel = await connection.channel()
# Maximum message count which will be processing at the same time.
await channel.set_qos(prefetch_count=100)
# Declaring queue
queue = await channel.declare_queue(queue_name, auto_delete=True)
await queue.consume(process_message)
try:
# Wait until terminate
await asyncio.Future()
finally:
await connection.close()
if __name__ == "__main__":
asyncio.run(main())
What I am not understanding is the use of async/await in this context. I found this tutorial that taught me of the use cases of these asyncio keywords. When I compare the information from this tutorial with the aio-pika code, however, it looks to me like the aio-pika code uses the chaining coroutines design pattern.
From the code in the tutorial, and things I tried out myself, it looks like these methods start and finish before going to the next one, making the program functionally synchronous. In this StackOverflow thread, someone asked a similar question. They asked if there is a reason to use asyncio without using methods that create a concurrent program, such as gather()
and create_task()
. The commenter replied that using asyncio has no use if the ‘code has no concurrency’. I am unsure what this entails exactly, but I think it refers to the code not having methods such as gather()
and create_task()
.
So, for instance, by putting the await
keyword in front of the connect_robust
function, what other code is able to run while connect_robust
would have to wait internally?
One guess I have is that the code inside the aio-pika library itself does use functions like gather()
that do make this code run asynchronously, and thus requires the await
word. But I cannot seem to find a definite answer that this could be the case.
This is the code that I played around with:
Asynchronous
import asyncio
async def count():
print("One")
await asyncio.sleep(1)
print("Two")
async def main():
await asyncio.gather(count(), count(), count())
if __name__ == "__main__":
asyncio.run(main())
One
One
One
Two
Two
Two
Synchronous (what aio-pika’s code looks like to me)
import asyncio
async def count():
print("One")
await asyncio.sleep(1)
print("Two")
async def main():
await count()
await count()
await count()
if __name__ == "__main__":
asyncio.run(main())
One
Two
One
Two
One
Two
Jens is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.