CSCI 338: Spring 2025

Software Engineering

CSCI 338: Spring 2025

AsyncIO Activity

Objective

Python’s asyncio library enables concurrent execution, which is important when you’re waiting around for things to finish. To explore this idea, let’s simulate a café where multiple customers place orders, and the barista prepares drinks concurrently.

Scenario

The café has one barista who prepares drinks. Without asyncio, the barista can only handle one order at a time:

  • Takes Alice’s order → Makes Alice’s Latte → Hands it to Alice.
  • Takes Bob’s order → Makes Bob’s Espresso → Hands it to Bob.
  • Takes Charlie’s order → Makes Charlie’s Cappuccino → Hands it to Charlie.

In other words, they can only start making the next drink after finishing the current one. However, with asyncio, the barista can start preparing drinks as soon as the order is placed.

Get Situated / Pull Down the Files

On GitHub: sync your fork of the class-exercises-spring2025 repo on GitHub.

On your local machine:

Synchronous Version (no asyncio)

Within the asyncio-activity directory you just made, add the following code to the cafe_sync.py file (I recommend that you do this within VS code, but it’s up to you):

Paste in the following code:

import time

def prepare_drink(customer, drink):
    print(f"{customer} ordered a {drink}.")
    time.sleep(2)  # Simulates time to make the drink
    print(f"{customer}'s {drink} is ready!")

def main():
    customers = [("Alice", "Latte"), ("Bob", "Espresso"), ("Charlie", "Cappuccino")]
    
    print("Starting orders...\n")
    for customer, drink in customers:
        prepare_drink(customer, drink)

    print("\nAll orders completed!")

if __name__ == "__main__":
    main()

Then run it. Note that each drink takes 2 seconds. Hence, the total time is ~6 seconds (3 drinks × 2 seconds)

Synchronous Version (with asyncio)

Now add the following code into cafe_async.py:

import asyncio

async def prepare_drink(customer, drink):
    print(f"{customer} ordered a {drink}.")
    await asyncio.sleep(2)  # Simulates time to make the drink
    print(f"{customer}'s {drink} is ready!")

async def main():
    customers = [("Alice", "Latte"), ("Bob", "Espresso"), ("Charlie", "Cappuccino")]
    
    print("Starting orders...\n")
    tasks = [prepare_drink(customer, drink) for customer, drink in customers]
    await asyncio.gather(*tasks)
    
    print("\nAll orders completed!")

if __name__ == "__main__":
    asyncio.run(main())

Run this file, and note:

Answer the following questions in answers.md