Reduce per-request DB overhead (Task 4)

- Cache setup_completed flag in app.state._setup_complete_cached after
  first successful is_setup_complete() call; all subsequent API requests
  skip the DB query entirely (one-way transition, cleared on restart).
- Add in-memory session token TTL cache (10 s) in require_auth; the second
  request with the same token within the window skips session_repo.get_session.
- Call invalidate_session_cache() on logout so revoked tokens are evicted
  immediately rather than waiting for TTL expiry.
- Add clear_session_cache() for test isolation.
- 5 new tests covering the cached fast-path for both optimisations.
- 460 tests pass, 83% coverage, zero ruff/mypy warnings.
This commit is contained in:
2026-03-10 19:16:00 +01:00
parent 44a5a3d70e
commit d931e8c6a3
7 changed files with 428 additions and 17 deletions

View File

@@ -289,12 +289,19 @@ class SetupRedirectMiddleware(BaseHTTPMiddleware):
return await call_next(request)
# If setup is not complete, block all other API requests.
if path.startswith("/api"):
# Fast path: setup completion is a one-way transition. Once it is
# True it is cached on app.state so all subsequent requests skip the
# DB query entirely. The flag is reset only when the app restarts.
if path.startswith("/api") and not getattr(
request.app.state, "_setup_complete_cached", False
):
db: aiosqlite.Connection | None = getattr(request.app.state, "db", None)
if db is not None:
from app.services import setup_service # noqa: PLC0415
if not await setup_service.is_setup_complete(db):
if await setup_service.is_setup_complete(db):
request.app.state._setup_complete_cached = True
else:
return RedirectResponse(
url="/api/setup",
status_code=status.HTTP_307_TEMPORARY_REDIRECT,