fix:修复音频代理缓存报错
This commit is contained in:
@@ -39,6 +39,9 @@ engine = create_async_engine(
|
||||
# Redis 连接
|
||||
redis_client = redis.from_url(settings.redis_url, decode_responses=True)
|
||||
|
||||
# Redis 二进制数据连接 (不自动解码响应,用于存储音频等二进制数据)
|
||||
redis_binary_client = redis.from_url(settings.redis_url, decode_responses=False)
|
||||
|
||||
# Redis 消息缓存连接 (db1) - 使用同步客户端在线程池中执行
|
||||
redis_message_client = sync_redis.from_url(settings.redis_url, decode_responses=True, db=1)
|
||||
|
||||
@@ -82,6 +85,11 @@ def get_redis():
|
||||
return redis_client
|
||||
|
||||
|
||||
def get_redis_binary():
|
||||
"""获取二进制数据专用的 Redis 客户端 (不自动解码响应)"""
|
||||
return redis_binary_client
|
||||
|
||||
|
||||
def get_redis_message():
|
||||
"""获取消息专用的 Redis 客户端 (db1)"""
|
||||
return redis_message_client
|
||||
|
||||
@@ -7,7 +7,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import Annotated
|
||||
|
||||
from app.dependencies.database import get_redis
|
||||
from app.dependencies.database import get_redis, get_redis_binary
|
||||
from app.service.audio_proxy_service import AudioProxyService, get_audio_proxy_service
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Path
|
||||
@@ -18,9 +18,12 @@ import redis.asyncio as redis
|
||||
router = APIRouter(prefix="/audio", tags=["Audio Proxy"])
|
||||
|
||||
|
||||
async def get_audio_proxy_dependency(redis_client: Annotated[redis.Redis, Depends(get_redis)]) -> AudioProxyService:
|
||||
async def get_audio_proxy_dependency(
|
||||
redis_binary_client: Annotated[redis.Redis, Depends(get_redis_binary)],
|
||||
redis_text_client: Annotated[redis.Redis, Depends(get_redis)],
|
||||
) -> AudioProxyService:
|
||||
"""音频代理服务依赖注入"""
|
||||
return get_audio_proxy_service(redis_client)
|
||||
return get_audio_proxy_service(redis_binary_client, redis_text_client)
|
||||
|
||||
|
||||
@router.get("/beatmapset/{beatmapset_id}")
|
||||
|
||||
@@ -14,10 +14,11 @@ import redis.asyncio as redis
|
||||
class AudioProxyService:
|
||||
"""音频代理服务"""
|
||||
|
||||
def __init__(self, redis_client: redis.Redis):
|
||||
self.redis = redis_client
|
||||
def __init__(self, redis_binary_client: redis.Redis, redis_text_client: redis.Redis):
|
||||
self.redis_binary = redis_binary_client
|
||||
self.redis_text = redis_text_client
|
||||
self.http_client = httpx.AsyncClient(timeout=30.0)
|
||||
self._cache_ttl = 7 * 24 * 60 * 60 # 7天缓存
|
||||
self._cache_ttl = 7 * 24 * 60 * 60
|
||||
|
||||
async def close(self):
|
||||
"""关闭HTTP客户端"""
|
||||
@@ -37,14 +38,14 @@ class AudioProxyService:
|
||||
cache_key = self._get_beatmapset_cache_key(beatmapset_id)
|
||||
metadata_key = self._get_beatmapset_metadata_key(beatmapset_id)
|
||||
|
||||
# 获取音频数据和元数据
|
||||
audio_data = await self.redis.get(cache_key)
|
||||
metadata = await self.redis.get(metadata_key)
|
||||
# 获取音频数据(二进制)和元数据(文本)
|
||||
audio_data = await self.redis_binary.get(cache_key)
|
||||
metadata = await self.redis_text.get(metadata_key)
|
||||
|
||||
if audio_data and metadata:
|
||||
logger.debug(f"Beatmapset audio cache hit for ID: {beatmapset_id}")
|
||||
# metadata 格式为 "content_type"
|
||||
return audio_data, metadata.decode()
|
||||
# audio_data 已经是 bytes 类型,metadata 是 str 类型
|
||||
return audio_data, metadata
|
||||
return None
|
||||
except (redis.RedisError, redis.ConnectionError) as e:
|
||||
logger.error(f"Error getting beatmapset audio from cache: {e}")
|
||||
@@ -56,9 +57,9 @@ class AudioProxyService:
|
||||
cache_key = self._get_beatmapset_cache_key(beatmapset_id)
|
||||
metadata_key = self._get_beatmapset_metadata_key(beatmapset_id)
|
||||
|
||||
# 缓存音频数据和元数据
|
||||
await self.redis.setex(cache_key, self._cache_ttl, audio_data)
|
||||
await self.redis.setex(metadata_key, self._cache_ttl, content_type)
|
||||
# 缓存音频数据(二进制)和元数据(文本)
|
||||
await self.redis_binary.setex(cache_key, self._cache_ttl, audio_data)
|
||||
await self.redis_text.setex(metadata_key, self._cache_ttl, content_type)
|
||||
|
||||
logger.debug(f"Cached beatmapset audio for ID: {beatmapset_id}, size: {len(audio_data)} bytes")
|
||||
except (redis.RedisError, redis.ConnectionError) as e:
|
||||
@@ -122,7 +123,7 @@ class AudioProxyService:
|
||||
return audio_data, content_type
|
||||
|
||||
|
||||
def get_audio_proxy_service(redis_client: redis.Redis) -> AudioProxyService:
|
||||
def get_audio_proxy_service(redis_binary_client: redis.Redis, redis_text_client: redis.Redis) -> AudioProxyService:
|
||||
"""获取音频代理服务实例"""
|
||||
# 每次创建新实例,避免全局状态
|
||||
return AudioProxyService(redis_client)
|
||||
return AudioProxyService(redis_binary_client, redis_text_client)
|
||||
|
||||
Reference in New Issue
Block a user