Skip to content

Commit dce80ea

Browse files
authored
fix: flush redis cache on API service startup (#1048)
## Summary - Flushes all Redis cache on API service startup to avoid stale/inconsistent responses after catalog updates - Adds proper lifespan handler to close Redis connection on shutdown Partial mitigation for #1047. ## Test plan - [x] Verified cache flush works on restart (set test key, restart, key is cleared) - [x] Verified API health and cache health endpoints still work - [x] Confirmed no external API endpoint exposes the flush functionality
2 parents 3c230dc + dc29967 commit dce80ea

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

backend/api/app/core/cache.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ async def clear_pattern(self, pattern: str) -> int:
7272
logger.error(f"Cache clear pattern error for {pattern}: {e}")
7373
return 0
7474

75+
async def flush_all(self) -> bool:
76+
"""Flush all keys from the current database"""
77+
try:
78+
await self.redis.flushdb()
79+
logger.info("Cache flushed successfully")
80+
return True
81+
except redis.RedisError as e:
82+
logger.error(f"Cache flush error: {e}")
83+
return False
84+
7585
async def get_stats(self) -> Dict[str, Any]:
7686
"""Get cache statistics"""
7787
try:

backend/api/app/core/dependencies.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,9 @@ async def get_cache_service() -> CacheService:
1414
settings = get_settings()
1515
_cache_service = CacheService(settings.REDIS_URL)
1616
return _cache_service
17+
18+
19+
def reset_cache_service() -> None:
20+
"""Reset the global cache service instance (used during shutdown)"""
21+
global _cache_service
22+
_cache_service = None

backend/api/app/main.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,37 @@
1+
import logging
2+
from contextlib import asynccontextmanager
3+
14
from fastapi import FastAPI
25
from fastapi.middleware.cors import CORSMiddleware
36

47
from app.api.v1 import cache, health, links, version
58
from app.core.config import get_settings
9+
from app.core.dependencies import get_cache_service, reset_cache_service
610

11+
logger = logging.getLogger(__name__)
712
settings = get_settings()
813

14+
15+
@asynccontextmanager
16+
async def lifespan(app: FastAPI):
17+
"""Startup and shutdown events for the application"""
18+
# Startup: flush cache to ensure fresh data after restart
19+
cache_service = await get_cache_service()
20+
await cache_service.flush_all()
21+
logger.info("Cache cleared on startup")
22+
yield
23+
# Shutdown: close cache connection and reset singleton
24+
await cache_service.close()
25+
reset_cache_service()
26+
27+
928
app = FastAPI(
1029
title="BRC Analytics API",
1130
version=settings.APP_VERSION,
1231
openapi_url="/api/openapi.json",
1332
docs_url="/api/docs",
1433
redoc_url="/api/redoc",
34+
lifespan=lifespan,
1535
)
1636

1737
app.add_middleware(

0 commit comments

Comments
 (0)