Functional Scope (In-Scope)
- Two-Phase Inventory Lock: Implement soft stock reservations (RESERVE) that roll back if checkout fails or expires (TTL).
- Zero Overselling: Guarantee thread safety during high volume concurrent purchases.
- Automated TTL Cleanup: Free up expired reservations asynchronously using highly efficient background workers.
- Stock Shortage Notifications (Observer Pattern): Watch threshold limits and trigger low-stock alerts to observers.
Explicit Boundaries (Out-of-Scope)
- No Complex Shipping logistics API: Excludes tracking warehouse labels, shipping containers, or coordinate tracking.
- No Automatic Purchase Order (PO) Builder: System design handles item counts; does not write real-world legal purchase contracts.
Practical reference implementations showing transactional inventory checkouts in Java and Python:
// ─── JAVA BLUEPRINT ──────────────────────────────────────────────────────────
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
interface InventoryObserver {
void onLowStock(String productId, int availableQty);
}
class RestockAlertSystem implements InventoryObserver {
@Override
public void onLowStock(String productId, int availableQty) {
System.out.println(String.format("[Alert] Product %s is running low on stock! Current: %d", productId, availableQty));
}
}
class Product {
private final String id;
private final String name;
private int availableQty;
private int reservedQty;
private final int lowStockThreshold;
private final List<InventoryObserver> observers = new CopyOnWriteArrayList<>();
private final ReentrantLock lock = new ReentrantLock();
public Product(String id, String name, int initialQty, int threshold) {
this.id = id;
this.name = name;
this.availableQty = initialQty;
this.reservedQty = 0;
this.lowStockThreshold = threshold;
}
public String getId() { return id; }
public String getName() { return name; }
public int getAvailableQty() {
lock.lock();
try { return availableQty; } finally { lock.unlock(); }
}
public void addObserver(InventoryObserver obs) { observers.add(obs); }
public boolean reserve(int qty) {
lock.lock();
try {
if (availableQty >= qty) {
availableQty -= qty;
reservedQty += qty;
checkThreshold();
return true;
}
return false;
} finally {
lock.unlock();
}
}
public void confirm(int qty) {
lock.lock();
try {
reservedQty = Math.max(0, reservedQty - qty);
} finally {
lock.unlock();
}
}
public void release(int qty) {
lock.lock();
try {
reservedQty = Math.max(0, reservedQty - qty);
availableQty += qty;
} finally {
lock.unlock();
}
}
public void restock(int qty) {
lock.lock();
try {
availableQty += qty;
} finally {
lock.unlock();
}
}
private void checkThreshold() {
if (availableQty <= lowStockThreshold) {
for (InventoryObserver obs : observers) {
obs.onLowStock(id, availableQty);
}
}
}
}
class Reservation {
private final String id;
private final String productId;
private final int quantity;
private final long expiryTime;
public Reservation(String id, String productId, int qty, long ttlMs) {
this.id = id;
this.productId = productId;
this.quantity = qty;
this.expiryTime = System.currentTimeMillis() + ttlMs;
}
public String getId() { return id; }
public String getProductId() { return productId; }
public int getQuantity() { return quantity; }
public boolean isExpired() { return System.currentTimeMillis() > expiryTime; }
}
class InventoryService {
private final Map<String, Product> products = new ConcurrentHashMap<>();
private final Map<String, Reservation> reservations = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
public InventoryService() {
scheduler.scheduleAtFixedRate(this::cleanExpiredReservations, 100, 100, TimeUnit.MILLISECONDS);
}
public void addProduct(Product p) { products.put(p.getId(), p); }
public boolean reserveStock(String reservationId, String productId, int qty, long ttlMs) {
Product p = products.get(productId);
if (p != null && p.reserve(qty)) {
reservations.put(reservationId, new Reservation(reservationId, productId, qty, ttlMs));
return true;
}
return false;
}
public boolean confirmPurchase(String reservationId) {
Reservation res = reservations.remove(reservationId);
if (res != null && !res.isExpired()) {
Product p = products.get(res.getProductId());
if (p != null) {
p.confirm(res.getQuantity());
System.out.println("[Service] Purchase confirmed for Reservation: " + reservationId);
return true;
}
}
return false;
}
private void cleanExpiredReservations() {
for (Reservation res : reservations.values()) {
if (res.isExpired()) {
if (reservations.remove(res.getId()) != null) {
Product p = products.get(res.getProductId());
if (p != null) {
p.release(res.getQuantity());
System.out.println(String.format("[TTL Cleanup] Released expired Reservation %s (%d units of %s)",
res.getId(), res.getQuantity(), p.getName()));
}
}
}
}
}
public void shutdown() {
scheduler.shutdown();
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
System.out.println("=== Inventory Management Simulation ===");
InventoryService service = new InventoryService();
RestockAlertSystem alertSystem = new RestockAlertSystem();
Product laptop = new Product("PROD-01", "MacBook Pro", 6, 2);
laptop.addObserver(alertSystem);
service.addProduct(laptop);
// Reserve Stock - Success
boolean r1 = service.reserveStock("RES-101", "PROD-01", 3, 200); // 200ms expiry
System.out.println("Reservation RES-101: " + (r1 ? "SUCCESS" : "FAILED"));
// Reserve Stock - Triggers Low Stock Alert
boolean r2 = service.reserveStock("RES-102", "PROD-01", 2, 1000);
System.out.println("Reservation RES-102: " + (r2 ? "SUCCESS" : "FAILED"));
// Let RES-101 expire (TTL)
Thread.sleep(300);
// Confirm RES-102 Purchase
service.confirmPurchase("RES-102");
service.shutdown();
}
}