Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ PropelAuth via `common/auth.py`. Routes get the authenticated user from `@auth.r

## Deployment
Deployed to Fly.io (`fly.toml`, app: `backend-ohack`, region: `sjc`). Uses gunicorn (`Procfile`). Port 6060.
⚠️ As of June 2026 prod runs ONE sync gunicorn worker (`Dockerfile` CMD `--workers 1`, default sync class) — a single slow request blocks the entire API. Fix plan (workers/threads, caching, Sentry error sweep, traffic evidence): `docs/perf-reliability-plan-2026-06.md`.

## Testing notes
- Tests live in `api/<domain>/tests/` or `test/` at the repo root.
Expand Down
10 changes: 7 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ RUN python -m venv venv && \
EXPOSE 6060

# Bind to both IPv4 and IPv6
ENV GUNICORN_CMD_ARGS="--bind=[::]:6060 --workers=2"
ENV GUNICORN_CMD_ARGS="--bind=[::]:6060"

# Put venv on PATH so installed CLI tools (e.g. git-fame) are accessible
ENV PATH="/app/venv/bin:$PATH"

# Copy project
COPY . /app/
# Run the application
CMD ["venv/bin/gunicorn", "api.wsgi:app", "--log-file=-", "--log-level", "debug", "--preload", "--workers", "1", "--timeout", "120"]
# Run the application: gthread worker class allows concurrent I/O-bound requests
# without head-of-line blocking from a single sync worker.
CMD ["venv/bin/gunicorn", "api.wsgi:app", "--log-file=-", "--log-level", "info", "--preload", "--worker-class", "gthread", "--workers", "2", "--threads", "8", "--timeout", "120"]
5 changes: 1 addition & 4 deletions Procfile
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
#web: gunicorn api.wsgi:app --python api --log-file=-

## For debug, use below
web: gunicorn api.wsgi:app --python api --log-file=- --log-level debug --preload --workers 1 --timeout 120
web: gunicorn api.wsgi:app --log-file=- --log-level info --preload --worker-class gthread --workers 2 --threads 8 --timeout 120
2 changes: 1 addition & 1 deletion api/judging/judging_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ def get_judge_event_details(judge_id: str, event_id: str) -> Dict:
user_id=judge_id, volunteer_type="judge", event_id=event_id
)
if not volunteer:
logger.error(f"Judge not found for user_id {judge_id} and event_id {event_id}")
logger.info(f"Judge not found for user_id {judge_id} and event_id {event_id}")
return {"error": "Judge not found"}, 404

logger.debug(f"Fetched judge details: {volunteer}")
Expand Down
Loading
Loading