refactor(api, chat): 改进异步处理并解决并发问题

内存可视化器 API 端点之前在异步路由中执行同步的阻塞操作(文件 I/O、数据处理)。在处理大型图文件时,这可能导致服务器冻结。现在,这些任务已被移至 ThreadPoolExecutor,从而使 API 非阻塞并显著提高响应速度。

在聊天消息管理器中,竞争条件可能导致消息处理重叠或中断后数据流停滞。此提交引入了:
- 并发锁(`is_chatter_processing`)以防止流循环同时运行多个 chatter 实例。
- 故障保护机制,在中断时重置处理状态,确保数据流能够恢复并正确继续。
This commit is contained in:
tt-P607
2025-12-02 14:40:58 +08:00
parent 1027c5abf7
commit 659a8e0d78
4 changed files with 860 additions and 115 deletions

View File

@@ -318,6 +318,15 @@ class StreamLoopManager:
has_messages = force_dispatch or await self._has_messages_to_process(context)
if has_messages:
# 🔒 并发保护:如果 Chatter 正在处理中,跳过本轮
# 这可能发生在1) 打断后重启循环 2) 处理时间超过轮询间隔
if context.is_chatter_processing:
logger.debug(f"🔒 [流工作器] stream={stream_id[:8]}, Chatter正在处理中跳过本轮")
# 不打印"开始处理"日志,直接进入下一轮等待
# 使用较短的等待时间,等待当前处理完成
await asyncio.sleep(1.0)
continue
if force_dispatch:
logger.info(f"⚡ [流工作器] stream={stream_id[:8]}, 任务ID={task_id}, 未读消息 {unread_count} 条,触发强制分发")
else:
@@ -477,10 +486,11 @@ class StreamLoopManager:
logger.warning(f"Chatter管理器未设置: {stream_id}")
return False
# 🔒 防止并发处理:如果已经在处理中,直接返回
# 🔒 二次并发保护(防御性检查)
# 正常情况下不应该触发,如果触发说明有竞态条件
if context.is_chatter_processing:
logger.debug(f"🔒 [并发保护] stream={stream_id[:8]}, Chatter 正在处理中,跳过本次处理请求")
return True # 返回 True这是正常的保护机制不是失败
logger.warning(f"🔒 [并发保护] stream={stream_id[:8]}, Chatter正在处理中(二次检查触发,可能存在竞态)")
return False
# 设置处理状态为正在处理
self._set_stream_processing_status(stream_id, True)
@@ -720,8 +730,8 @@ class StreamLoopManager:
chat_manager = get_chat_manager()
chat_stream = await chat_manager.get_stream(stream_id)
if chat_stream and not chat_stream.group_info:
# 私聊:有消息时几乎立即响应,空转时稍微等待
min_interval = 0.1 if has_messages else 3.0
# 私聊:有消息时快速响应,空转时稍微等待
min_interval = 0.5 if has_messages else 5.0
logger.debug(f"{stream_id} 私聊模式,使用最小间隔: {min_interval:.2f}s")
return min_interval
except Exception as e: