T-05: Remove app.state mutation from _build_app_context

Move session cache initialization from per-request _build_app_context to
startup lifespan handler. The session cache type is now decided once at app
startup based on settings, making _build_app_context pure (read-only).

Changes:
- Move cache initialization logic to new _update_session_cache() in main.py
- Call _update_session_cache() during lifespan startup to initialize cache
- Remove three if/elif/elif branches mutating state.session_cache from _build_app_context
- Add cache swap logic to set_runtime_settings() in runtime_state.py to handle
  runtime settings changes (e.g., setup wizard updates)
- Keep app.state.session_cache initialization in create_app() for test compatibility

This ensures:
- _build_app_context is pure and doesn't mutate app state on each request
- Session cache configuration decisions are centralized at startup
- Settings changes during runtime (via setup wizard) also trigger cache swap
- Cache initialization logic is isolated in one place

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-25 18:23:08 +02:00
parent d467190eb1
commit e57d19fd76
3 changed files with 41 additions and 10 deletions

View File

@@ -28,13 +28,13 @@ from app.repositories.protocols import (
GeoCacheRepository,
HistoryArchiveRepository,
ImportLogRepository,
SettingsRepository,
SessionRepository,
SettingsRepository,
)
from app.services.geo_cache import GeoCache
from app.utils.constants import SESSION_COOKIE_NAME
from app.utils.runtime_state import RuntimeState
from app.utils.session_cache import InMemorySessionCache, NoOpSessionCache, SessionCache
from app.utils.session_cache import NoOpSessionCache, SessionCache
log: structlog.stdlib.BoundLogger = structlog.get_logger()
@@ -91,13 +91,6 @@ def _build_app_context(request: Request) -> ApplicationContext:
session_cache = getattr(state, "session_cache", None)
if session_cache is None:
session_cache = NoOpSessionCache()
state.session_cache = session_cache
elif _session_cache_enabled(state.settings) and isinstance(session_cache, NoOpSessionCache):
session_cache = InMemorySessionCache()
state.session_cache = session_cache
elif not _session_cache_enabled(state.settings) and not isinstance(session_cache, NoOpSessionCache):
session_cache = NoOpSessionCache()
state.session_cache = session_cache
return ApplicationContext(
settings=state.settings,