Merge pull request 'Bound readiness probe latency' (#72) from timmy/71-bound-readiness-probe-latency into main
This commit is contained in:
commit
af7f2ff92a
16
src/main.py
16
src/main.py
|
|
@ -15,6 +15,7 @@ from src.views import router as frontend_router
|
|||
app = FastAPI(title="Stackchain Dashboard")
|
||||
CONTEXT_TIMEOUT_SECONDS = 5.0
|
||||
EVENT_STREAM_TIMEOUT_SECONDS = 5.0
|
||||
READINESS_TIMEOUT_SECONDS = 5.0
|
||||
FRONTEND_DIR = Path(__file__).resolve().parent.parent / "frontend"
|
||||
|
||||
app.add_middleware(
|
||||
|
|
@ -39,15 +40,26 @@ def health() -> dict[str, str]:
|
|||
async def readiness():
|
||||
"""Return readiness after verifying the configured Gitea connection."""
|
||||
try:
|
||||
user = await current_user()
|
||||
user = await asyncio.wait_for(
|
||||
current_user(), timeout=READINESS_TIMEOUT_SECONDS
|
||||
)
|
||||
except Exception as exc:
|
||||
timed_out = isinstance(exc, TimeoutError)
|
||||
error_message = (
|
||||
f"Gitea readiness check timed out after {READINESS_TIMEOUT_SECONDS:g}s"
|
||||
if timed_out
|
||||
else str(exc)
|
||||
)
|
||||
return JSONResponse(
|
||||
{
|
||||
"status": "not_ready",
|
||||
"service": "stackchain-dashboard",
|
||||
"error": str(exc),
|
||||
"error": error_message,
|
||||
},
|
||||
status_code=503,
|
||||
headers={
|
||||
"Retry-After": str(max(1, math.ceil(READINESS_TIMEOUT_SECONDS)))
|
||||
} if timed_out else None,
|
||||
)
|
||||
return {
|
||||
"status": "ready",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import asyncio
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from src import main
|
||||
|
|
@ -37,3 +40,29 @@ async def test_readiness_endpoint_returns_503_when_gitea_is_unavailable(monkeypa
|
|||
assert response.status_code == 503
|
||||
assert b'"status":"not_ready"' in response.body
|
||||
assert b'"error":"connection refused"' in response.body
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_readiness_endpoint_times_out_and_cancels_stalled_gitea_check(monkeypatch):
|
||||
cancelled = asyncio.Event()
|
||||
|
||||
async def hanging_user():
|
||||
try:
|
||||
await asyncio.sleep(0.05)
|
||||
return {"login": "too-late"}
|
||||
finally:
|
||||
cancelled.set()
|
||||
|
||||
monkeypatch.setattr(main, "READINESS_TIMEOUT_SECONDS", 0.01, raising=False)
|
||||
monkeypatch.setattr(main, "current_user", hanging_user)
|
||||
|
||||
response = await main.readiness()
|
||||
|
||||
assert response.status_code == 503
|
||||
assert response.headers["retry-after"] == "1"
|
||||
assert json.loads(response.body) == {
|
||||
"status": "not_ready",
|
||||
"service": "stackchain-dashboard",
|
||||
"error": "Gitea readiness check timed out after 0.01s",
|
||||
}
|
||||
assert cancelled.is_set()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user