mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-11 20:18:30 +08:00
76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
|
|
"""缓存装饰器工具"""
|
|||
|
|
|
|||
|
|
import functools
|
|||
|
|
import json
|
|||
|
|
from typing import Any, Callable, Optional
|
|||
|
|
|
|||
|
|
from src.core.logger import logger
|
|||
|
|
|
|||
|
|
from src.clients.redis_client import get_redis_client_sync
|
|||
|
|
|
|||
|
|
|
|||
|
|
def cache_result(key_prefix: str, ttl: int = 60, user_specific: bool = True) -> Callable:
|
|||
|
|
"""
|
|||
|
|
缓存函数结果的装饰器
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
key_prefix: 缓存键前缀
|
|||
|
|
ttl: 缓存过期时间(秒)
|
|||
|
|
user_specific: 是否针对用户缓存(从 context.user.id 获取)
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
def decorator(func: Callable) -> Callable:
|
|||
|
|
@functools.wraps(func)
|
|||
|
|
async def wrapper(*args, **kwargs) -> Any:
|
|||
|
|
redis_client = get_redis_client_sync()
|
|||
|
|
|
|||
|
|
# 如果 Redis 不可用,直接执行原函数
|
|||
|
|
if redis_client is None:
|
|||
|
|
return await func(*args, **kwargs)
|
|||
|
|
|
|||
|
|
# 构建缓存键
|
|||
|
|
try:
|
|||
|
|
# 从 args 中获取 context(通常是第一个参数)
|
|||
|
|
context = args[0] if args else None
|
|||
|
|
|
|||
|
|
if user_specific and context and hasattr(context, "user") and context.user:
|
|||
|
|
cache_key = f"{key_prefix}:user:{context.user.id}"
|
|||
|
|
else:
|
|||
|
|
cache_key = f"{key_prefix}:global"
|
|||
|
|
|
|||
|
|
# 如果有额外的参数(如 days),添加到键中
|
|||
|
|
if hasattr(args[0], "__dict__"):
|
|||
|
|
# 如果是 dataclass 或对象,获取其属性
|
|||
|
|
for attr_name in ["days", "limit"]:
|
|||
|
|
if hasattr(args[0], attr_name):
|
|||
|
|
attr_value = getattr(args[0], attr_name)
|
|||
|
|
cache_key += f":{attr_name}:{attr_value}"
|
|||
|
|
|
|||
|
|
# 尝试从缓存获取
|
|||
|
|
cached = await redis_client.get(cache_key)
|
|||
|
|
if cached:
|
|||
|
|
logger.debug(f"缓存命中: {cache_key}")
|
|||
|
|
return json.loads(cached)
|
|||
|
|
|
|||
|
|
# 执行原函数
|
|||
|
|
result = await func(*args, **kwargs)
|
|||
|
|
|
|||
|
|
# 保存到缓存
|
|||
|
|
try:
|
|||
|
|
await redis_client.setex(
|
|||
|
|
cache_key, ttl, json.dumps(result, ensure_ascii=False, default=str)
|
|||
|
|
)
|
|||
|
|
logger.debug(f"缓存已保存: {cache_key}, TTL: {ttl}s")
|
|||
|
|
except Exception as e:
|
|||
|
|
logger.warning(f"保存缓存失败: {e}")
|
|||
|
|
|
|||
|
|
return result
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
logger.warning(f"缓存处理出错: {e}, 直接执行原函数")
|
|||
|
|
return await func(*args, **kwargs)
|
|||
|
|
|
|||
|
|
return wrapper
|
|||
|
|
|
|||
|
|
return decorator
|