fix(database): 修复缓存失效逻辑和属性名错误
主要修复: 1. Expression 缓存键生成问题 - 问题: get_expression_by_chat_id 作为实例方法使用 @cached 时,self 会污染缓存键 - 解决: 重构为静态方法 _get_expressions_by_chat_id_cached,实例方法调用它 - 确保缓存键只包含 chat_id,与缓存失效键匹配 2. PersonInfo 删除时的缓存失效 - 问题: person_id 是哈希值,无法反向得到 platform 和 user_id - 解决: 移除不准确的缓存清除代码,依赖 TTL 自动过期 - 原因: 删除操作很罕见,缓存在 5-10 分钟内会自动过期 3. ChatStreams 属性名错误 (严重 bug) - 问题: UserInfo.nickname 应为 UserInfo.user_nickname - 问题: UserInfo.cardname 应为 UserInfo.user_cardname - 错误导致: AttributeError: 'UserInfo' object has no attribute 'nickname' - 修复: 使用正确的属性名 验证: - 创建了 test_cache_invalidation.py 验证缓存键一致性 - 所有 11 个测试通过 - 验证了缓存失效键与装饰器生成的键匹配
This commit is contained in:
@@ -232,7 +232,6 @@ class ExpressionLearner:
|
|||||||
logger.error(f"为聊天流 {self.chat_name} 触发学习失败: {e}")
|
logger.error(f"为聊天流 {self.chat_name} 触发学习失败: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@cached(ttl=600, key_prefix="chat_expressions")
|
|
||||||
async def get_expression_by_chat_id(self) -> tuple[list[dict[str, float]], list[dict[str, float]]]:
|
async def get_expression_by_chat_id(self) -> tuple[list[dict[str, float]], list[dict[str, float]]]:
|
||||||
"""
|
"""
|
||||||
获取指定chat_id的style和grammar表达方式(带10分钟缓存)
|
获取指定chat_id的style和grammar表达方式(带10分钟缓存)
|
||||||
@@ -240,12 +239,19 @@ class ExpressionLearner:
|
|||||||
|
|
||||||
优化: 使用CRUD和缓存,减少数据库访问
|
优化: 使用CRUD和缓存,减少数据库访问
|
||||||
"""
|
"""
|
||||||
|
# 使用静态方法以正确处理缓存键
|
||||||
|
return await self._get_expressions_by_chat_id_cached(self.chat_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@cached(ttl=600, key_prefix="chat_expressions")
|
||||||
|
async def _get_expressions_by_chat_id_cached(chat_id: str) -> tuple[list[dict[str, float]], list[dict[str, float]]]:
|
||||||
|
"""内部方法:从数据库获取表达方式(带缓存)"""
|
||||||
learnt_style_expressions = []
|
learnt_style_expressions = []
|
||||||
learnt_grammar_expressions = []
|
learnt_grammar_expressions = []
|
||||||
|
|
||||||
# 使用CRUD查询
|
# 使用CRUD查询
|
||||||
crud = CRUDBase(Expression)
|
crud = CRUDBase(Expression)
|
||||||
all_expressions = await crud.get_all_by(chat_id=self.chat_id)
|
all_expressions = await crud.get_all_by(chat_id=chat_id)
|
||||||
|
|
||||||
for expr in all_expressions:
|
for expr in all_expressions:
|
||||||
# 确保create_date存在,如果不存在则使用last_active_time
|
# 确保create_date存在,如果不存在则使用last_active_time
|
||||||
@@ -256,7 +262,7 @@ class ExpressionLearner:
|
|||||||
"style": expr.style,
|
"style": expr.style,
|
||||||
"count": expr.count,
|
"count": expr.count,
|
||||||
"last_active_time": expr.last_active_time,
|
"last_active_time": expr.last_active_time,
|
||||||
"source_id": self.chat_id,
|
"source_id": chat_id,
|
||||||
"type": expr.type,
|
"type": expr.type,
|
||||||
"create_date": create_date,
|
"create_date": create_date,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -450,8 +450,8 @@ class ChatManager:
|
|||||||
defaults={
|
defaults={
|
||||||
"user_platform": user_info.platform if user_info else platform,
|
"user_platform": user_info.platform if user_info else platform,
|
||||||
"user_id": user_info.user_id if user_info else "",
|
"user_id": user_info.user_id if user_info else "",
|
||||||
"user_nickname": user_info.nickname if user_info else "",
|
"user_nickname": user_info.user_nickname if user_info else "",
|
||||||
"user_cardname": user_info.cardname if user_info else "",
|
"user_cardname": user_info.user_cardname if user_info else "",
|
||||||
"group_platform": group_info.platform if group_info else None,
|
"group_platform": group_info.platform if group_info else None,
|
||||||
"group_id": group_info.group_id if group_info else None,
|
"group_id": group_info.group_id if group_info else None,
|
||||||
"group_name": group_info.group_name if group_info else None,
|
"group_name": group_info.group_name if group_info else None,
|
||||||
|
|||||||
@@ -539,14 +539,9 @@ class PersonInfoManager:
|
|||||||
if record:
|
if record:
|
||||||
await crud.delete(record.id)
|
await crud.delete(record.id)
|
||||||
|
|
||||||
# 清除相关缓存
|
# 注意: 删除操作很少发生,缓存会在TTL过期后自动清除
|
||||||
from src.common.database.optimization.cache_manager import get_cache
|
# 无法从person_id反向得到platform和user_id,因此无法精确清除缓存
|
||||||
from src.common.database.utils.decorators import generate_cache_key
|
# 删除后的查询仍会返回正确结果(None/False)
|
||||||
cache = await get_cache()
|
|
||||||
|
|
||||||
# 清除所有相关的person缓存
|
|
||||||
await cache.delete(generate_cache_key("person_known", p_id))
|
|
||||||
await cache.delete(generate_cache_key("person_field", p_id))
|
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user