feat: add Redis-backed rate limiter with configurable backend
Add RedisRateLimiter using sorted-set sliding window alongside the existing InMemoryRateLimiter. Users choose via RATE_LIMIT_BACKEND (memory|redis) with RATE_LIMIT_REDIS_URL falling back to RQ_REDIS_URL. Redis backend validates connectivity at startup and fails open on transient errors during requests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
Abhimanyu Saharan
parent
ee825fb2d5
commit
fc9fc1661c
@@ -34,6 +34,8 @@ from app.api.users import router as users_router
|
||||
from app.core.config import settings
|
||||
from app.core.error_handling import install_error_handling
|
||||
from app.core.logging import configure_logging, get_logger
|
||||
from app.core.rate_limit import validate_rate_limit_redis
|
||||
from app.core.rate_limit_backend import RateLimitBackend
|
||||
from app.core.security_headers import SecurityHeadersMiddleware
|
||||
from app.db.session import init_db
|
||||
from app.schemas.health import HealthStatusResponse
|
||||
@@ -437,6 +439,11 @@ async def lifespan(_: FastAPI) -> AsyncIterator[None]:
|
||||
settings.db_auto_migrate,
|
||||
)
|
||||
await init_db()
|
||||
if settings.rate_limit_backend == RateLimitBackend.REDIS:
|
||||
validate_rate_limit_redis(settings.rate_limit_redis_url)
|
||||
logger.info("app.lifecycle.rate_limit backend=redis")
|
||||
else:
|
||||
logger.info("app.lifecycle.rate_limit backend=memory")
|
||||
logger.info("app.lifecycle.started")
|
||||
try:
|
||||
yield
|
||||
|
||||
Reference in New Issue
Block a user