Review
Scale live-quiz shards by bumping SHARD_COUNT
PulseArena (live trivia) is crushing Friday-night peaks on 4 Postgres shards. This PR raises SHARD_COUNT to 8 and rewires the FastAPI quiz-state router so sessions hash across the new fleet. Ops says the extra replicas are already provisioned and healthy.
FastAPITier 7shardingroutingmigrationdistributed
Click a line to flag it, pick one or more labels, then submit. If the change looks correct, approve it.
app/routing/quiz_shards.py+2-1
| 1 | 1 | from fastapi import APIRouter, HTTPException | |
| 2 | 2 | from app.db.pool import shard_pools | |
| 3 | 3 | ||
| 4 | 4 | router = APIRouter(prefix="/v1/quiz", tags=["quiz"]) | |
| 5 | - | SHARD_COUNT = 4 # must match provisioned quiz_state_* DBs | |
| 5 | + | SHARD_COUNT = 8 # scaled out for Friday prime-time load | |
| 6 | 6 | ||
| 7 | 7 | def shard_for_user(user_id: int) -> int: | |
| 8 | 8 | """Map a player onto a quiz_state shard.""" | |
| 9 | 9 | return user_id % SHARD_COUNT | |
| 10 | 10 | ||
| 11 | 11 | @router.get("/sessions/{user_id}/state") | |
| 12 | 12 | async def get_quiz_state(user_id: int): | |
| 13 | 13 | shard = shard_for_user(user_id) | |
| 14 | + | # New shards 4-7 are empty until traffic naturally fills them — fine for cold start. | |
| 14 | 15 | pool = shard_pools[shard] | |
| 15 | 16 | row = await pool.fetchrow( | |
| 16 | 17 | "SELECT streak, current_q, score FROM quiz_state WHERE user_id = $1", | |
| 17 | 18 | user_id, | |
| 18 | 19 | ) | |
| 19 | 20 | if row is None: | |
| 20 | 21 | raise HTTPException(status_code=404, detail="no active quiz session") | |
| 21 | 22 | return dict(row) |