Anuj2209's picture
Finalize checkpoint-first evaluation and sandbox submission workflow.
0572d06
Raw
History Blame Contribute Delete
3.03 kB
"""Database sandbox service."""
from __future__ import annotations
import time
from collections import deque
from typing import Any
from fastapi import FastAPI
from pydantic import BaseModel
from starlette.responses import PlainTextResponse
app = FastAPI(title="sandbox-database", version="0.1.0")
STARTED = time.time()
ACTIVE_FAILURE: str | None = None
LOGS: deque[str] = deque(maxlen=500)
DATA: dict[str, dict[str, Any]] = {"txn-001": {"status": "ok", "amount": 42.0}}
class ChaosInjectRequest(BaseModel):
failure_mode: str
severity: str = "high"
class QueryRequest(BaseModel):
key: str
def _now() -> str:
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
def _log(level: str, message: str, **extra: Any) -> None:
payload = {"ts": _now(), "service": "database", "level": level, "message": message, **extra}
LOGS.append(str(payload))
def _status() -> str:
if ACTIVE_FAILURE in {"oom", "query_timeout"}:
return "down"
if ACTIVE_FAILURE in {"connection_pool_exhaustion", "replication_lag"}:
return "degraded"
return "healthy"
@app.get("/health")
def health() -> dict[str, Any]:
return {"service": "database", "status": _status(), "failure_mode": ACTIVE_FAILURE, "uptime_s": int(time.time() - STARTED)}
@app.get("/metrics", response_class=PlainTextResponse)
def metrics() -> str:
status = _status()
health_value = {"healthy": 1.0, "degraded": 0.5, "down": 0.0}[status]
error_rate = 0.01 if status == "healthy" else (0.3 if status == "degraded" else 0.98)
latency = 0.03 if status == "healthy" else (0.45 if status == "degraded" else 3.5)
return (
f'service_health{{service="database"}} {health_value}\n'
f'service_error_rate{{service="database"}} {error_rate}\n'
f'service_latency_seconds{{service="database",quantile="0.99"}} {latency}\n'
)
@app.get("/logs")
def logs(lines: int = 50) -> dict[str, Any]:
size = max(1, min(lines, 500))
return {"service": "database", "entries": list(LOGS)[-size:]}
@app.post("/chaos/inject")
def inject(req: ChaosInjectRequest) -> dict[str, Any]:
global ACTIVE_FAILURE
ACTIVE_FAILURE = req.failure_mode
_log("WARN", "failure injected", failure_mode=req.failure_mode, severity=req.severity)
return {"status": "ok", "service": "database", "failure_mode": ACTIVE_FAILURE}
@app.post("/chaos/clear")
def clear() -> dict[str, Any]:
global ACTIVE_FAILURE
ACTIVE_FAILURE = None
_log("INFO", "failure cleared")
return {"status": "ok", "service": "database", "failure_mode": ACTIVE_FAILURE}
@app.post("/query")
def query(req: QueryRequest) -> dict[str, Any]:
if _status() == "down":
_log("ERROR", "query failed", reason="database down")
return {"ok": False, "error": "database_down"}
if ACTIVE_FAILURE == "replication_lag":
_log("WARN", "serving stale record", key=req.key)
return {"ok": True, "stale": True, "record": DATA.get(req.key)}
return {"ok": True, "record": DATA.get(req.key)}