refactor: 第二轮架构缺陷修复 (1/2/3/4/9/10)
1. 内存泄漏修复:RealtimeChatManager 添加会话自动清理机制
- 每10次操作检查超时会话(1小时无活动自动清理)
- 最大活跃会话数限制500,超限清理最旧会话
2. 数据库索引补全:
- Conversation: session_id, work_order_id 添加索引
- WorkOrder: status 添加索引
- ChatSession: user_id 添加索引
- KnowledgeEntry: category, is_active, is_verified 添加索引
3. ServiceManager 线程安全:
- 添加 threading.Lock 双重检查锁
- 防止多线程并发初始化同一服务
4. API 响应格式统一:
- 新增 api_response() 标准响应函数
- 统一格式: {success, message, data} / {success, error}
9. asyncio 误用修复:
- knowledge.py 文件上传改用安全的 asyncio 调用方式
- 兼容已有事件循环和无事件循环两种场景
10. 请求限流:
- 新增 rate_limit 装饰器(按 IP 限流)
- chat/message 限制 20次/分钟
- workorder/ai-suggestion 限制 5次/分钟
This commit is contained in:
@@ -32,15 +32,49 @@ class ChatMessage:
|
||||
class RealtimeChatManager:
|
||||
"""实时对话管理器"""
|
||||
|
||||
# 会话超时时间(秒):超过此时间无活动的会话自动清理
|
||||
SESSION_TIMEOUT = 3600 # 1小时
|
||||
# 最大同时活跃会话数
|
||||
MAX_ACTIVE_SESSIONS = 500
|
||||
|
||||
def __init__(self):
|
||||
self.llm_client = QwenClient()
|
||||
self.knowledge_manager = KnowledgeManager()
|
||||
self.vehicle_manager = VehicleDataManager()
|
||||
self.active_sessions = {} # 存储活跃的对话会话
|
||||
self.message_history = {} # 存储消息历史
|
||||
self.active_sessions = {}
|
||||
self.message_history = {}
|
||||
self._cleanup_counter = 0
|
||||
|
||||
def _cleanup_expired_sessions(self):
|
||||
"""清理超时的会话,每 10 次操作触发一次检查"""
|
||||
self._cleanup_counter += 1
|
||||
if self._cleanup_counter < 10:
|
||||
return
|
||||
self._cleanup_counter = 0
|
||||
|
||||
now = datetime.now()
|
||||
expired = [
|
||||
sid for sid, s in self.active_sessions.items()
|
||||
if (now - s.get("last_activity", now)).total_seconds() > self.SESSION_TIMEOUT
|
||||
]
|
||||
for sid in expired:
|
||||
self.active_sessions.pop(sid, None)
|
||||
self.message_history.pop(sid, None)
|
||||
if expired:
|
||||
logger.info(f"清理了 {len(expired)} 个超时会话,当前活跃: {len(self.active_sessions)}")
|
||||
|
||||
# 如果超过上限,清理最旧的
|
||||
if len(self.active_sessions) > self.MAX_ACTIVE_SESSIONS:
|
||||
sorted_sessions = sorted(self.active_sessions.items(), key=lambda x: x[1].get("last_activity", datetime.min))
|
||||
to_remove = len(self.active_sessions) - self.MAX_ACTIVE_SESSIONS
|
||||
for sid, _ in sorted_sessions[:to_remove]:
|
||||
self.active_sessions.pop(sid, None)
|
||||
self.message_history.pop(sid, None)
|
||||
logger.warning(f"会话数超限,清理了 {to_remove} 个最旧会话")
|
||||
|
||||
def create_session(self, user_id: str, work_order_id: Optional[int] = None, tenant_id: Optional[str] = None) -> str:
|
||||
"""创建新的对话会话"""
|
||||
self._cleanup_expired_sessions()
|
||||
session_id = f"session_{user_id}_{int(time.time())}"
|
||||
|
||||
session_data = {
|
||||
|
||||
Reference in New Issue
Block a user