diff --git a/src/routers/deriver_metrics.py b/src/routers/deriver_metrics.py index 6ab79b2a..547a5153 100644 --- a/src/routers/deriver_metrics.py +++ b/src/routers/deriver_metrics.py @@ -1,18 +1,15 @@ -"""Deriver work metrics as JSON. Errors rather than serving a stale number.""" +"""Deriver work metrics as JSON, with the age of the measurement alongside them.""" from logging import getLogger from fastapi import APIRouter, HTTPException from src.backlog import DeriverMetricsPoller -from src.config import settings logger = getLogger(__name__) router = APIRouter(prefix="/deriver", tags=["deriver"]) -MAX_SNAPSHOT_AGE_INTERVALS = 3 - _poller: DeriverMetricsPoller | None = None @@ -21,13 +18,6 @@ def set_deriver_metrics_poller(poller: DeriverMetricsPoller | None) -> None: _poller = poller -def max_snapshot_age_seconds() -> float: - return float( - settings.DERIVER.BACKLOG_METRICS_POLL_INTERVAL_SECONDS - * MAX_SNAPSHOT_AGE_INTERVALS - ) - - @router.get("/metrics") async def get_deriver_metrics_response() -> dict[str, float | int]: """Seconds of outstanding deriver work, plus the raw counts behind it.""" @@ -37,15 +27,6 @@ async def get_deriver_metrics_response() -> dict[str, float | int]: status_code=503, detail="No deriver measurement available yet" ) - age = snapshot.age_seconds - if age is None or age > max_snapshot_age_seconds(): - raise HTTPException( - status_code=503, - detail=f"Deriver measurement is stale ({age:.0f}s old)" - if age is not None - else "Deriver measurement is stale", - ) - return { "outstanding_work_seconds": snapshot.signal_seconds, "eligible_work_units": snapshot.stats.eligible_work_units, @@ -56,5 +37,5 @@ async def get_deriver_metrics_response() -> dict[str, float | int]: "embeddings_pending_due": snapshot.stats.embeddings_pending_due, "dreams_due": snapshot.dreams_due, "measured_at": snapshot.measured_at, - "measurement_age_seconds": age, + "measurement_age_seconds": snapshot.age_seconds or 0.0, } diff --git a/tests/test_deriver_metrics.py b/tests/test_deriver_metrics.py index 4c3a2ec5..a5d59c3a 100644 --- a/tests/test_deriver_metrics.py +++ b/tests/test_deriver_metrics.py @@ -162,20 +162,21 @@ class TestDeriverMetricsRoute: assert excinfo.value.status_code == 503 - async def test_errors_when_the_measurement_is_stale(self): + async def test_serves_an_old_snapshot_with_its_age(self): + """The caller decides what is too old, from measurement_age_seconds.""" poller = DeriverMetricsPoller() poller._snapshot = DeriverMetricsSnapshot( # pyright: ignore[reportPrivateUsage] - signal_seconds=0.0, - measured_at=time.time() - (deriver_metrics.max_snapshot_age_seconds() + 60), + signal_seconds=7.0, + measured_at=time.time() - 3600, ) deriver_metrics.set_deriver_metrics_poller(poller) try: - with pytest.raises(HTTPException) as excinfo: - await deriver_metrics.get_deriver_metrics_response() + body = await deriver_metrics.get_deriver_metrics_response() finally: deriver_metrics.set_deriver_metrics_poller(None) - assert excinfo.value.status_code == 503 + assert body["outstanding_work_seconds"] == 7.0 + assert body["measurement_age_seconds"] >= 3600 async def test_errors_when_no_poller_is_registered(self): deriver_metrics.set_deriver_metrics_poller(None)