加入图片缓存,每次从文件系统中提取相关的图片,加载成bytes,后续使用时直接从缓存中提取。减少IO读取次数,提高发送性能

This commit is contained in:
liuwei
2025-06-24 10:06:19 +08:00
parent 4db938df0b
commit b50ece6546
5 changed files with 342 additions and 8 deletions
+54 -6
View File
@@ -2,6 +2,7 @@ from pathlib import Path
from loguru import logger
import os
import base64
from typing import Dict, Any, List, Optional, Tuple
from db.connection import DBConnectionManager
@@ -60,6 +61,8 @@ class XiurenImagePlugin(MessagePluginInterface):
self.image_folder = str(Path(Path(__file__).parent.parent.parent, "xiuren"))
# 注册功能权限
self.feature = self.register_feature()
# 初始化图片缓存管理器
self.image_cache_manager = None
def initialize(self, context: Dict[str, Any]) -> bool:
"""初始化插件"""
@@ -78,6 +81,9 @@ class XiurenImagePlugin(MessagePluginInterface):
if config_image_folder:
self.image_folder = config_image_folder
# 从配置获取缓存大小,默认5张
cache_size = self._config.get("XiurenImage", {}).get("cache_size", 5)
# 检查图片文件夹是否存在
try:
if not os.path.exists(self.image_folder):
@@ -86,7 +92,10 @@ class XiurenImagePlugin(MessagePluginInterface):
except Exception as e:
self.LOG.error(f"创建图片文件夹失败: {e}")
self.LOG.info(f"[{self.name}] 插件初始化完成,指令:{self._commands},图片目录:{self.image_folder}")
# 初始化图片缓存管理器
self.image_cache_manager = ImageCacheManager(self.image_folder, cache_size)
self.LOG.info(f"[{self.name}] 插件初始化完成,指令:{self._commands},图片目录:{self.image_folder},缓存大小:{cache_size}")
return True
def start(self) -> bool:
@@ -127,10 +136,9 @@ class XiurenImagePlugin(MessagePluginInterface):
return False, "没有权限"
try:
# 获取随机图片
pic_path = self._get_random_pic()
self.LOG.info(f"返回图片地址:{pic_path}")
if not pic_path:
# 从缓存获取图片bytes数据
cached_image = self._get_cached_image()
if not cached_image:
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender),
f"❌未找到图片资源",
sender)
@@ -138,9 +146,16 @@ class XiurenImagePlugin(MessagePluginInterface):
return False, "未找到图片资源"
# 发送图片
image_data = cached_image['bytes']
image_path = cached_image['path']
# 记录缓存状态
cache_count = self.image_cache_manager.get_cached_image_count()
self.LOG.info(f"从缓存获取图片成功,路径:{image_path},当前缓存数量:{cache_count}")
# 发送图片,支持bytes格式
client_msg_id, create_time, new_msg_id = await bot.send_image_message((roomid if roomid else sender),
Path(pic_path))
image_data)
# revoke.add_message_to_revoke(roomid, client_msg_id, create_time, new_msg_id, 90)
self.LOG.info(
f"发送图片结果,client_msg_id= {client_msg_id},create_time={create_time},new_msg_id={new_msg_id}")
@@ -150,6 +165,39 @@ class XiurenImagePlugin(MessagePluginInterface):
self.LOG.error(f"处理图片请求出错: {e}")
return False, f"处理出错: {e}"
def _get_cached_image(self) -> Optional[Dict[str, any]]:
"""
从缓存获取图片数据
返回格式: {'path': str, 'bytes': bytes}
"""
try:
# 优先从内存缓存获取
cached_image = self.image_cache_manager.get_cached_image_bytes()
if cached_image:
return cached_image
# 如果缓存中没有,回退到原来的方式
self.LOG.warning("缓存中没有图片,回退到磁盘读取")
pic_path = self._get_random_pic()
if pic_path:
# 读取图片bytes
try:
with open(pic_path, 'rb') as f:
image_bytes = f.read()
return {
'path': pic_path,
'bytes': image_bytes
}
except Exception as e:
self.LOG.error(f"读取图片文件失败: {e}")
return None
return None
except Exception as e:
self.LOG.error(f"获取缓存图片失败: {e}")
return None
def _get_random_pic(self) -> Optional[str]:
"""
从 Redis 随机获取图片路径