agentscope-ai / agentscope-ai/QwenPaw

[Bug] 服务重启时当前会话的最后几条消息丢失(shutdown_handler 为空导致)

Đang mở
#4,791 2 bình luận 0 reaction 0 người được giao Xem trên GitHub
wontfix
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

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.