perf(napcat): 为 API 调用添加缓存并优化异步任务
- 为 NapCat 适配器中的 `get_group_info`, `get_member_info` 和 `get_self_info` 函数实现了一个简单的内存缓存(5分钟过期)。此举旨在减少对后端服务的重复 API 请求,从而提升性能并降低被限速的风险。 - 将 `ContextManager` 中对 `start_stream_loop` 的调用修改为 `asyncio.create_task`,使其成为一个非阻塞操作,避免在添加消息时因等待循环启动而造成延迟。
This commit is contained in:
@@ -59,7 +59,7 @@ class SingleStreamContextManager:
|
|||||||
self.total_messages += 1
|
self.total_messages += 1
|
||||||
self.last_access_time = time.time()
|
self.last_access_time = time.time()
|
||||||
# 启动流的循环任务(如果还未启动)
|
# 启动流的循环任务(如果还未启动)
|
||||||
await stream_loop_manager.start_stream_loop(self.stream_id)
|
asyncio.create_task(stream_loop_manager.start_stream_loop(self.stream_id))
|
||||||
logger.debug(f"添加消息{message.processed_plain_text}到单流上下文: {self.stream_id}")
|
logger.debug(f"添加消息{message.processed_plain_text}到单流上下文: {self.stream_id}")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -275,7 +275,7 @@ class SingleStreamContextManager:
|
|||||||
self.last_access_time = time.time()
|
self.last_access_time = time.time()
|
||||||
|
|
||||||
# 启动流的循环任务(如果还未启动)
|
# 启动流的循环任务(如果还未启动)
|
||||||
await stream_loop_manager.start_stream_loop(self.stream_id)
|
asyncio.create_task(stream_loop_manager.start_stream_loop(self.stream_id))
|
||||||
|
|
||||||
logger.debug(f"添加消息到单流上下文(异步): {self.stream_id} (兴趣度待计算)")
|
logger.debug(f"添加消息到单流上下文(异步): {self.stream_id} (兴趣度待计算)")
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -6,6 +6,33 @@ import urllib3
|
|||||||
import ssl
|
import ssl
|
||||||
import io
|
import io
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import time
|
||||||
|
from asyncio import Lock
|
||||||
|
|
||||||
|
_internal_cache = {}
|
||||||
|
_cache_lock = Lock()
|
||||||
|
CACHE_TIMEOUT = 300 # 缓存5分钟
|
||||||
|
|
||||||
|
|
||||||
|
async def get_from_cache(key: str):
|
||||||
|
async with _cache_lock:
|
||||||
|
data = _internal_cache.get(key)
|
||||||
|
if not data:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result, timestamp = data
|
||||||
|
if time.time() - timestamp < CACHE_TIMEOUT:
|
||||||
|
logger.debug(f"从缓存命中: {key}")
|
||||||
|
return result
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
async def set_to_cache(key: str, value: any):
|
||||||
|
async with _cache_lock:
|
||||||
|
_internal_cache[key] = (value, time.time())
|
||||||
|
|
||||||
|
|
||||||
from .database import BanUser, db_manager
|
from .database import BanUser, db_manager
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
|
|
||||||
@@ -27,11 +54,16 @@ class SSLAdapter(urllib3.PoolManager):
|
|||||||
|
|
||||||
async def get_group_info(websocket: Server.ServerConnection, group_id: int) -> dict | None:
|
async def get_group_info(websocket: Server.ServerConnection, group_id: int) -> dict | None:
|
||||||
"""
|
"""
|
||||||
获取群相关信息
|
获取群相关信息 (带缓存)
|
||||||
|
|
||||||
返回值需要处理可能为空的情况
|
返回值需要处理可能为空的情况
|
||||||
"""
|
"""
|
||||||
logger.debug("获取群聊信息中")
|
cache_key = f"group_info:{group_id}"
|
||||||
|
cached_data = await get_from_cache(cache_key)
|
||||||
|
if cached_data:
|
||||||
|
return cached_data
|
||||||
|
|
||||||
|
logger.debug(f"获取群聊信息中 (无缓存): {group_id}")
|
||||||
request_uuid = str(uuid.uuid4())
|
request_uuid = str(uuid.uuid4())
|
||||||
payload = json.dumps({"action": "get_group_info", "params": {"group_id": group_id}, "echo": request_uuid})
|
payload = json.dumps({"action": "get_group_info", "params": {"group_id": group_id}, "echo": request_uuid})
|
||||||
try:
|
try:
|
||||||
@@ -43,8 +75,11 @@ async def get_group_info(websocket: Server.ServerConnection, group_id: int) -> d
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"获取群信息失败: {e}")
|
logger.error(f"获取群信息失败: {e}")
|
||||||
return None
|
return None
|
||||||
logger.debug(socket_response)
|
|
||||||
return socket_response.get("data")
|
data = socket_response.get("data")
|
||||||
|
if data:
|
||||||
|
await set_to_cache(cache_key, data)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
async def get_group_detail_info(websocket: Server.ServerConnection, group_id: int) -> dict | None:
|
async def get_group_detail_info(websocket: Server.ServerConnection, group_id: int) -> dict | None:
|
||||||
@@ -71,11 +106,16 @@ async def get_group_detail_info(websocket: Server.ServerConnection, group_id: in
|
|||||||
|
|
||||||
async def get_member_info(websocket: Server.ServerConnection, group_id: int, user_id: int) -> dict | None:
|
async def get_member_info(websocket: Server.ServerConnection, group_id: int, user_id: int) -> dict | None:
|
||||||
"""
|
"""
|
||||||
获取群成员信息
|
获取群成员信息 (带缓存)
|
||||||
|
|
||||||
返回值需要处理可能为空的情况
|
返回值需要处理可能为空的情况
|
||||||
"""
|
"""
|
||||||
logger.debug("获取群成员信息中")
|
cache_key = f"member_info:{group_id}:{user_id}"
|
||||||
|
cached_data = await get_from_cache(cache_key)
|
||||||
|
if cached_data:
|
||||||
|
return cached_data
|
||||||
|
|
||||||
|
logger.debug(f"获取群成员信息中 (无缓存): group={group_id}, user={user_id}")
|
||||||
request_uuid = str(uuid.uuid4())
|
request_uuid = str(uuid.uuid4())
|
||||||
payload = json.dumps(
|
payload = json.dumps(
|
||||||
{
|
{
|
||||||
@@ -93,8 +133,11 @@ async def get_member_info(websocket: Server.ServerConnection, group_id: int, use
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"获取成员信息失败: {e}")
|
logger.error(f"获取成员信息失败: {e}")
|
||||||
return None
|
return None
|
||||||
logger.debug(socket_response)
|
|
||||||
return socket_response.get("data")
|
data = socket_response.get("data")
|
||||||
|
if data:
|
||||||
|
await set_to_cache(cache_key, data)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
async def get_image_base64(url: str) -> str:
|
async def get_image_base64(url: str) -> str:
|
||||||
@@ -137,13 +180,18 @@ def convert_image_to_gif(image_base64: str) -> str:
|
|||||||
|
|
||||||
async def get_self_info(websocket: Server.ServerConnection) -> dict | None:
|
async def get_self_info(websocket: Server.ServerConnection) -> dict | None:
|
||||||
"""
|
"""
|
||||||
获取自身信息
|
获取自身信息 (带缓存)
|
||||||
Parameters:
|
Parameters:
|
||||||
websocket: WebSocket连接对象
|
websocket: WebSocket连接对象
|
||||||
Returns:
|
Returns:
|
||||||
data: dict: 返回的自身信息
|
data: dict: 返回的自身信息
|
||||||
"""
|
"""
|
||||||
logger.debug("获取自身信息中")
|
cache_key = "self_info"
|
||||||
|
cached_data = await get_from_cache(cache_key)
|
||||||
|
if cached_data:
|
||||||
|
return cached_data
|
||||||
|
|
||||||
|
logger.debug("获取自身信息中 (无缓存)")
|
||||||
request_uuid = str(uuid.uuid4())
|
request_uuid = str(uuid.uuid4())
|
||||||
payload = json.dumps({"action": "get_login_info", "params": {}, "echo": request_uuid})
|
payload = json.dumps({"action": "get_login_info", "params": {}, "echo": request_uuid})
|
||||||
try:
|
try:
|
||||||
@@ -155,8 +203,11 @@ async def get_self_info(websocket: Server.ServerConnection) -> dict | None:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"获取自身信息失败: {e}")
|
logger.error(f"获取自身信息失败: {e}")
|
||||||
return None
|
return None
|
||||||
logger.debug(response)
|
|
||||||
return response.get("data")
|
data = response.get("data")
|
||||||
|
if data:
|
||||||
|
await set_to_cache(cache_key, data)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
def get_image_format(raw_data: str) -> str:
|
def get_image_format(raw_data: str) -> str:
|
||||||
|
|||||||
Reference in New Issue
Block a user