feat: implement Redis caching for analytics endpoints with fallback to database
Test / test (push) Successful in 15s
Test / test (push) Successful in 15s
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Application middleware components."""
|
||||
@@ -0,0 +1,38 @@
|
||||
"""Middleware that logs cache availability transitions."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from starlette.types import ASGIApp, Receive, Scope, Send
|
||||
|
||||
from app.core.cache import cache_manager
|
||||
from app.core.config import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CacheAvailabilityMiddleware:
|
||||
"""Logs when Redis cache becomes unavailable or recovers."""
|
||||
|
||||
def __init__(self, app: ASGIApp) -> None:
|
||||
self.app = app
|
||||
self._last_state: bool | None = None
|
||||
|
||||
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
|
||||
if scope["type"] == "http" and settings.redis_enabled:
|
||||
self._log_transition()
|
||||
await self.app(scope, receive, send)
|
||||
|
||||
def _log_transition(self) -> None:
|
||||
available = cache_manager.is_available
|
||||
if self._last_state is None:
|
||||
self._last_state = available
|
||||
if not available:
|
||||
logger.warning("Redis cache unavailable, serving responses without cache")
|
||||
return
|
||||
if available == self._last_state:
|
||||
return
|
||||
if available:
|
||||
logger.info("Redis cache connectivity restored; caching re-enabled")
|
||||
else:
|
||||
logger.warning("Redis cache unavailable, serving responses without cache")
|
||||
self._last_state = available
|
||||
Reference in New Issue
Block a user