Start learning free

LESSON 181 OF 188 · BACKEND: INTERVIEW QUESTIONS

Hold Stock for 10 Minutes in Python

Practice

The interview question: “A customer adds the last items to their cart. Hold them for 10 minutes so nobody else can buy them. If the customer never pays, the stock must come back by itself. How do you build it?”

The expected answer: don't change the stock and don't run a cleanup job. Save each hold with the time it expires, and compute the free stock when someone asks: available = stock − the holds that haven't expired yet. An expired hold simply stops being counted, so its stock comes back at the right second. A new hold that asks for more than is available gets 409.

Counting only what's still alive, on another value: coupons that are valid until a time.

coupons = [{"code": "SPRING", "until": 500}, {"code": "SUMMER", "until": 900}]
live = []
for coupon in coupons:
    if coupon["until"] > now():
        live.append(coupon["code"])
# at second 600, live is ["SUMMER"]

Time comes from now(), given in the starting code; the tests set it with an X-Test-Clock header. A hold lasts HOLD_SECONDS, 600 seconds. Product 6 has 4 in stock:

clock 1000  GET /products/6/available  →  200  {"product_id": 6, "available": 4}
clock 1000  POST /holds {"cart_id": "cart-1", "product_id": 6, "quantity": 3}
            →  201  {"hold_id": 1, "cart_id": "cart-1", "product_id": 6, "quantity": 3, "expires_at": 1600}
clock 1000  GET /products/6/available  →  200  {"product_id": 6, "available": 1}
clock 1100  POST /holds {"cart_id": "cart-2", "product_id": 6, "quantity": 2}
            →  409  {"error": "Not enough stock", "available": 1}
clock 1100  POST /holds {"cart_id": "cart-2", "product_id": 6, "quantity": 1}
            →  201  {"hold_id": 2, "cart_id": "cart-2", "product_id": 6, "quantity": 1, "expires_at": 1700}
clock 1599  GET /products/6/available  →  200  {"product_id": 6, "available": 0}
clock 1600  GET /products/6/available  →  200  {"product_id": 6, "available": 3}
clock 1600  POST /holds {"cart_id": "cart-3", "product_id": 6, "quantity": 3}
            →  201  {"hold_id": 3, "cart_id": "cart-3", "product_id": 6, "quantity": 3, "expires_at": 2200}
clock 1700  GET /products/6/available  →  200  {"product_id": 6, "available": 1}

Your task: the holds table, both routes and the insert are written. Make available take off the holds that are still alive, and make POST /holds answer 409 with what's free when the cart asks for more.


Assignment
Follow the Coding Tutorial to count only live holds in available and to refuse a hold that is too big.


Hint
A hold is alive while its expires_at is later than now(): at exactly second 1600, cart-1's hold is gone. add_hold calls available too, so both routes count the same way.


STEP 1 OF 6
    Ctrl + Enter to check

    Bq Stock Hold in Python

    Keep going with Python1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free