fix(app): cancel readiness loop on lifespan shutdown (review round 2)

_readiness_refresh_loop is started with tg.start_soon and loops forever with no
shutdown_event check. anyio waits for start_soon tasks on normal task-group exit
rather than cancelling them, so graceful shutdown hung until uvicorn's timeout.
Cancel the task group's scope after teardown() to stop the loop and any
stragglers, mirroring _maybe_login_flow_cleanup.

Also document the cache ttl_seconds startup-override and the inclusive is_stale
boundary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-06-10 21:52:48 +02:00
co-authored by Claude Opus 4.8
parent cc2ce6e853
commit fc62a30384
2 changed files with 9 additions and 0 deletions
@@ -70,6 +70,7 @@ class ReadinessCache(BaseModel):
if not self.statuses:
return True
current = time.monotonic() if now is None else now
# Inclusive boundary: exactly ttl_seconds old counts as stale.
return any(
current - status.checked_at >= self.ttl_seconds
for status in self.statuses.values()