agentscope-ai / agentscope-ai/QwenPaw
[Bug] 服务重启时当前会话的最后几条消息丢失(shutdown_handler 为空导致)
- Ngôn ngữ chính
- Python
- Star
- 34.9k
- Fork
- 3.1k
- Merge trung bình
- 1 ngày 15 giờ
- Pull request đã merge (30 ngày)
- 225
Mô tả
描述
当 `qwenpaw app` 被 systemd 重启或接收到 SIGTERM 时,当前正在进行的会话的最后几条消息可能丢失。重启后回到之前的会话状态,最新的对话内容消失。
## 复现步骤
1. 通过控制台/频道与 QwenPaw 进行多轮对话
2. 在对话过程中执行 `sudo systemctl restart qwenpaw`(或进程收到 SIGTERM)
3. 服务重启后,打开控制台,发现该会话的最后几条消息丢失
## 根因分析
### 代码位置
`qwenpaw/app/runner/runner.py`
### 问题一:`shutdown_handler` 为空
```python
# L978
async def shutdown_handler(self, *args, **kwargs):
"""
Shutdown handler.
"""
# 空实现!不做任何保存
```
当 `Runner.stop()` 被调用时(服务关闭流程),它依次调用:
1. `self.shutdown_handler()` ← 空,什么也不做
2. `self._exit_stack.aclose()`
3. 设置 `_health = False`
完整的关闭链:`_app.py shutdown → MultiAgentManager.stop_all() → Workspace.stop() → ServiceManager.stop_all() → Runner.stop() → shutdown_handler()`
### 问题二:消息保存依赖 finally 块
正常消息处理后,状态在 `query_handler` 的 `finally` 块中保存:
```python
# L940
finally:
if agent is not None and session_state_loaded:
...
await self.session.save_session_state(
session_id=session_id,
user_id=user_id,
channel=channel,
agent=agent,
)
```
当服务收到 SIGTERM 时,如果进程正在 `query_handler` 中处理消息(如在流式输出过程中),`finally` 块可能来不及执行,导致该次交换的消息未写入磁盘。
## 建议修复
在 `AgentRunner` 中增加关闭时的会话状态保存机制:
1. `__init__` 中增加 `self._pending_session_state = None`
2. `query_handler` 的 `finally` 块中缓存 `agent.state_dict()` 快照
3. `shutdown_handler` 中检查缓存快照并写入磁盘
具体补丁代码见附件或参考 #issue-comment。
## 环境
- QwenPaw 版本:1.1.9
- 部署方式:pip 安装 + systemd 服务
- 操作系统:Linux
Hướng dẫn đóng góp
Đánh giá
Issue này chưa được đánh giá.