Files
DjangoAdmin_FastAPI_EleVue/core/redis_client.py
T
ClaudeandClaude 63bebedf05 feat(phase5): 解耦与收尾清理
- core/redis_client.py 移除 scheduler 耦合,lifespan 由 core/app.py 组合(Redis→调度器→Redis)
- main.py 改从 core.app 导入 create_app
- 删除 apps/、extensions/ 目录;utils 删除已迁移垫片与死代码 formatter.py
- 新增 deploy/(nginx、supervisor)、scripts/(init_db、seed)、logs/(结构化日志落盘)
- core/app.py 接入 core.logger setup_logging
- 更新 CLAUDE.md 反映 core/shared/modules 新结构

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 10:16:44 +08:00

73 lines
2.1 KiB
Python

"""
Redis客户端核心模块(由 utils/redis_ctx.py 迁移而来)
封装 Redis 连接管理和请求级上下文注入:
- lifespan 中创建连接池,关闭时断开
- 每个请求通过中间件将 Redis 客户端注入 contextvars
- 业务代码通过 get_redis() 获取当前请求的 Redis 客户端
"""
import logging
from contextvars import ContextVar
from contextlib import asynccontextmanager
from fastapi import FastAPI
from redis.asyncio import Redis
from redis import asyncio as aioredis
from config import REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, REDIS_INDEX, REDIS_AUTH
logger = logging.getLogger(__name__)
# 请求级 Redis 客户端上下文变量
_redis_ctx: ContextVar[Redis] = ContextVar('_redis_ctx')
def get_redis() -> Redis:
"""获取当前请求的 Redis 客户端"""
return _redis_ctx.get()
def _build_redis_url() -> str:
"""构建 Redis 连接 URL"""
if REDIS_AUTH and REDIS_PASSWORD:
return f"redis://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/{REDIS_INDEX}"
return f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_INDEX}"
async def create_redis_pool() -> Redis:
"""创建 Redis 异步连接池"""
redis = await aioredis.from_url(
_build_redis_url(),
encoding="utf-8",
decode_responses=True,
protocol=2
)
return redis
@asynccontextmanager
async def redis_lifespan(app: FastAPI):
"""Redis 生命周期管理,替代已废弃的 on_event("startup"/"shutdown")"""
# startup: 创建连接池
redis = await create_redis_pool()
await redis.ping()
app.state.redis = redis
print(f"Redis 连接成功 --> {REDIS_HOST}:{REDIS_PORT}/{REDIS_INDEX}")
logger.info(f"Redis 连接成功: {REDIS_HOST}:{REDIS_PORT}/{REDIS_INDEX}")
yield
# shutdown: 关闭连接
await redis.aclose()
app.state.redis = None
logger.info("Redis 连接已关闭")
async def redis_middleware(request, call_next):
"""Redis 上下文注入中间件,每个请求开始时将 Redis 客户端注入 contextvars"""
redis = getattr(request.app.state, 'redis', None)
if redis is not None:
_redis_ctx.set(redis)
return await call_next(request)