╔══════════════════════════════════════════════════════════════════════════════╗ ║ MULTI-WORKER FASTAPI ARCHITECTURE ║ ╚══════════════════════════════════════════════════════════════════════════════╝ ┌─────────────────────────────────────────────────────────────────────────────┐ │ Command: uvicorn alpine_bits_python.api:app --workers 4 │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Master Process (uvicorn supervisor) ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ │ │ │ │ ┌───────────┼──────────┼──────────┼──────────┼───────────┐ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ▼ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌──────────────────┐ │Worker 0│ │Worker 1│ │Worker 2│ │Worker 3│ │Lock File │ │PID:1001│ │PID:1002│ │PID:1003│ │PID:1004│ │/tmp/alpinebits │ └────┬───┘ └───┬────┘ └───┬────┘ └───┬────┘ │_primary_worker │ │ │ │ │ │.lock │ │ │ │ │ └──────────────────┘ │ │ │ │ ▲ │ │ │ │ │ └─────────┴──────────┴──────────┴─────────────┤ All try to acquire lock │ │ │ ▼ │ ┌───────────────────────┐ │ │ fcntl.flock(LOCK_EX) │────────────┘ │ Non-blocking attempt │ └───────────────────────┘ │ ┏━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━┓ ▼ ▼ ┌─────────┐ ┌──────────────┐ │SUCCESS │ │ WOULD BLOCK │ │(First) │ │(Others) │ └────┬────┘ └──────┬───────┘ │ │ ▼ ▼ ╔════════════════════════════════╗ ╔══════════════════════════════╗ ║ PRIMARY WORKER ║ ║ SECONDARY WORKERS ║ ║ (Worker 0, PID 1001) ║ ║ (Workers 1-3) ║ ╠════════════════════════════════╣ ╠══════════════════════════════╣ ║ ║ ║ ║ ║ ✓ Handle HTTP requests ║ ║ ✓ Handle HTTP requests ║ ║ ✓ Start email scheduler ║ ║ ✗ Skip email scheduler ║ ║ ✓ Send daily reports ║ ║ ✗ Skip daily reports ║ ║ ✓ Run DB migrations ║ ║ ✗ Skip DB migrations ║ ║ ✓ Hash customers (startup) ║ ║ ✗ Skip customer hashing ║ ║ ✓ Send error alerts ║ ║ ✓ Send error alerts ║ ║ ✓ Process webhooks ║ ║ ✓ Process webhooks ║ ║ ✓ AlpineBits endpoints ║ ║ ✓ AlpineBits endpoints ║ ║ ║ ║ ║ ║ Holds: worker_lock ║ ║ worker_lock = None ║ ║ ║ ║ ║ ╚════════════════════════════════╝ ╚══════════════════════════════╝ │ │ │ │ └──────────┬───────────────────────────┘ │ ▼ ┌───────────────────────────┐ │ Incoming HTTP Request │ └───────────────────────────┘ │ (Load balanced by OS) │ ┌───────────┴──────────────┐ │ │ ▼ ▼ Any worker can handle Round-robin distribution the request normally across all 4 workers ╔══════════════════════════════════════════════════════════════════════════════╗ ║ SINGLETON SERVICES ║ ╚══════════════════════════════════════════════════════════════════════════════╝ Only run on PRIMARY worker: ┌─────────────────────────────────────────────────────────────┐ │ Email Scheduler │ │ ├─ Daily Report: 8:00 AM │ │ └─ Stats Collection: Per-hotel reservation counts │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ Startup Tasks (One-time) │ │ ├─ Database table creation │ │ ├─ Customer data hashing/backfill │ │ └─ Configuration validation │ └─────────────────────────────────────────────────────────────┘ ╔══════════════════════════════════════════════════════════════════════════════╗ ║ SHARED SERVICES ║ ╚══════════════════════════════════════════════════════════════════════════════╝ Run on ALL workers (primary + secondary): ┌─────────────────────────────────────────────────────────────┐ │ HTTP Request Handling │ │ ├─ Webhook endpoints (/api/webhook/*) │ │ ├─ AlpineBits endpoints (/api/alpinebits/*) │ │ └─ Health checks (/api/health) │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ Error Alert Handler │ │ └─ Any worker can send immediate error alerts │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ Event Dispatching │ │ └─ Background tasks triggered by webhooks │ └─────────────────────────────────────────────────────────────┘ ╔══════════════════════════════════════════════════════════════════════════════╗ ║ SHUTDOWN & FAILOVER ║ ╚══════════════════════════════════════════════════════════════════════════════╝ Graceful Shutdown: ┌─────────────────────────────────────────────────────────────┐ │ 1. SIGTERM received │ │ 2. Stop scheduler (primary only) │ │ 3. Close email handler │ │ 4. Release worker_lock (primary only) │ │ 5. Dispose database engine │ └─────────────────────────────────────────────────────────────┘ Primary Worker Crash: ┌─────────────────────────────────────────────────────────────┐ │ 1. Primary worker crashes │ │ 2. OS automatically releases file lock │ │ 3. Secondary workers continue handling requests │ │ 4. On next restart, first worker becomes new primary │ └─────────────────────────────────────────────────────────────┘ ╔══════════════════════════════════════════════════════════════════════════════╗ ║ KEY BENEFITS ║ ╚══════════════════════════════════════════════════════════════════════════════╝ ✓ No duplicate email notifications ✓ No race conditions in database operations ✓ Automatic failover if primary crashes ✓ Load distribution for HTTP requests ✓ No external dependencies (Redis, etc.) ✓ Simple and reliable