agentscope-ai / agentscope-ai/QwenPaw

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

Aperta
#4,791 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub
wontfix
Lingua principale
TypeScript
Stelle
35k
Fork
3.1k
Merge medio
1g 13h
PR unite (30g)
228

Descrizione

描述

当 `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

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.