Spaces:
Sleeping
Sleeping
| """ | |
| Buggy FastAPI server for the incident1 scenario. | |
| Serves three endpoints and runs a background job worker thread. | |
| The worker crash-loops because it hits a poisoned DB record. | |
| """ | |
| import json | |
| import logging | |
| import os | |
| import sqlite3 | |
| import sys | |
| import threading | |
| import time | |
| import uvicorn | |
| from fastapi import FastAPI | |
| from fastapi.responses import JSONResponse | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s %(levelname)s %(name)s: %(message)s", | |
| stream=sys.stdout, | |
| ) | |
| logger = logging.getLogger("buggy_server") | |
| app = FastAPI() | |
| _DB_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "app.db") | |
| def _get_conn() -> sqlite3.Connection: | |
| conn = sqlite3.connect(_DB_PATH) | |
| conn.row_factory = sqlite3.Row | |
| return conn | |
| # ββ Endpoints ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def health(): | |
| return {"status": "ok"} | |
| def list_jobs(): | |
| conn = _get_conn() | |
| rows = conn.execute( | |
| "SELECT id, payload, status FROM jobs ORDER BY id" | |
| ).fetchall() | |
| conn.close() | |
| return {"jobs": [dict(r) for r in rows]} | |
| def checkout(): | |
| """Process the next pending job. Returns 500 if the payload is malformed.""" | |
| conn = _get_conn() | |
| row = conn.execute( | |
| "SELECT * FROM jobs WHERE status='pending' ORDER BY id LIMIT 1" | |
| ).fetchone() | |
| if not row: | |
| conn.close() | |
| return {"status": "no_pending_jobs"} | |
| try: | |
| data = json.loads(row["payload"]) | |
| conn.execute( | |
| "UPDATE jobs SET status='completed' WHERE id=?", (row["id"],) | |
| ) | |
| conn.commit() | |
| conn.close() | |
| return {"status": "ok", "job_id": row["id"], "data": data} | |
| except Exception as exc: | |
| conn.close() | |
| return JSONResponse( | |
| status_code=500, | |
| content={"error": f"Serialization Error: {exc}", "job_id": row["id"]}, | |
| ) | |
| # ββ Worker loop ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def _worker_loop() -> None: | |
| """Run worker.process_jobs() in a tight restart loop (crash-loop visible in logs).""" | |
| # Ensure the workdir (where worker.py lives) is importable | |
| workdir = os.path.dirname(os.path.abspath(__file__)) | |
| if workdir not in sys.path: | |
| sys.path.insert(0, workdir) | |
| import worker | |
| while True: | |
| try: | |
| worker.process_jobs() | |
| except Exception as exc: | |
| logger.error("[WORKER CRASH] %s: %s", type(exc).__name__, exc) | |
| time.sleep(0.5) | |
| def _start_worker() -> None: | |
| t = threading.Thread(target=_worker_loop, daemon=True, name="worker-loop") | |
| t.start() | |
| logger.info("Worker thread started") | |
| if __name__ == "__main__": | |
| port = int(os.environ.get("BUGGY_SERVER_PORT", 9000)) | |
| uvicorn.run(app, host="0.0.0.0", port=port, log_config=None) | |