Let a pinned minute read runs from the whole day

/observability/runs gains since/until, so the throughput chart's pin asks
the server for its minute instead of filtering a fixed recent list. This
engine writes ~60 runs a minute, so any minute but the newest read empty.

since is inclusive and until exclusive, matching the minute buckets the
charts are drawn from. Hover stays the client-side preview it was:
scrubbing a day would otherwise be a request per minute rested on.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017MeiWk3Yq12n2pTvnQWYvt
This commit is contained in:
2026-08-17 00:27:40 +02:00
co-authored by Claude Fable 5
parent affb0a5f8c
commit 0b91379914
7 changed files with 94 additions and 12 deletions
+16 -1
View File
@@ -97,6 +97,11 @@ def _since(hours: int) -> datetime:
return datetime.now(timezone.utc) - timedelta(hours=hours)
def _aware(when: datetime) -> datetime:
"""A bound as the columns store it. A naive one is read as UTC."""
return when if when.tzinfo else when.replace(tzinfo=timezone.utc)
@router.get("/summary", response_model=HealthSummary)
async def read_summary(
request: Request, controller: FlowControllerDep, session: SessionDep
@@ -275,14 +280,24 @@ def read_runs(
session: SessionDep,
flow: str | None = None,
status: str | None = None,
since: datetime | None = None,
until: datetime | None = None,
limit: int = 50,
) -> Any:
"""Recent cascades, newest first."""
"""Recent cascades, newest first.
``since`` is inclusive and ``until`` exclusive, so a window of one minute
holds exactly the runs of the minute bucket the charts are drawn from.
"""
statement = select(FlowRun).order_by(col(FlowRun.started_at).desc())
if flow:
statement = statement.where(col(FlowRun.flow) == flow)
if status:
statement = statement.where(col(FlowRun.status) == status)
if since:
statement = statement.where(col(FlowRun.started_at) >= _aware(since))
if until:
statement = statement.where(col(FlowRun.started_at) < _aware(until))
return list(session.exec(statement.limit(min(limit, 200))))
@@ -102,3 +102,35 @@ def test_the_history_reads_back(
dead = client.get(f"{PREFIX}/dead-letter", headers=superuser_token_headers)
assert dead.status_code == 200
assert isinstance(dead.json(), list)
def test_runs_narrow_to_one_minute(
client: TestClient, superuser_token_headers: dict[str, str], db: Session
) -> None:
"""A minute picked off a chart reaches past what the recent list holds."""
minute = datetime.now(timezone.utc).replace(second=0, microsecond=0) - timedelta(
hours=3
)
db.add(FlowRun(id="minute-in", flow=FLOW, started_at=minute, status="ok"))
db.add(
FlowRun(
id="minute-after",
flow=FLOW,
started_at=minute + timedelta(minutes=1),
status="ok",
)
)
db.commit()
runs = client.get(
f"{PREFIX}/runs",
headers=superuser_token_headers,
params={
"since": minute.isoformat(),
"until": (minute + timedelta(minutes=1)).isoformat(),
},
).json()
# The upper bound is exclusive, so the run starting the next minute is not
# in this one.
assert [run["id"] for run in runs] == ["minute-in"]