agentscope-ai / agentscope-ai/QwenPaw

[Bug]: idle cleanup can remove a newly recreated queue state

オープン
#6,372 コメント 1 件 リアクション 0 件 担当者 1 名 @rayrayraykk が担当を希望しています GitHub で見る
主要言語
TypeScript
スター
35k
フォーク
3.1k
平均マージ
1日 13時間
マージ済み PR(30日)
228

説明

## QwenPaw Version

Current `main` commit: `4acf3418b0d2a5a66726308c881a426f9e189f9b`.

## Description

`UnifiedQueueManager._cleanup_idle_queues()` removes an idle queue entry from `_queues` before cancelling and awaiting its consumer. `_run_consumer()` then unconditionally executes `self._queues.pop(queue_key, None)` in its `finally` block.

If a new payload for the same key arrives after cleanup removes the old entry but before the old consumer finishes cancellation, `enqueue()` creates and registers a new `QueueState`. When the old consumer finally exits, its unconditional `pop()` removes that new state. The new consumer continues running but is no longer tracked, so later messages can create another consumer for the same session key.

**Related PR(s):** None.

**Security considerations:** None identified; this is queue lifecycle correctness.

## Component(s) Affected

- [x] Core / Backend (app, agents, config, providers, utils, local_models)
- [ ] Console (frontend web UI)
- [x] Channels (DingTalk, Feishu, QQ, Discord, iMessage, etc.)
- [ ] Skills
- [ ] CLI
- [ ] Documentation (website)
- [x] Tests
- [ ] CI/CD
- [ ] Scripts / Deploy

## Environment

- **QwenPaw version:** current `main` commit `4acf3418b0d2a5a66726308c881a426f9e189f9b`
- **OS:** Windows 11
- **Install method:** from source
- **Python version:** 3.11

## Steps to Reproduce

1. Start a `UnifiedQueueManager` with a consumer that has drained its first payload and is waiting indefinitely.
2. Let idle cleanup remove that empty queue and cancel the first consumer, but pause its cancellation cleanup before it returns.
3. Enqueue another payload for the same `(channel_id, session_id, priority_level)` key, creating a new queue state.
4. Allow the first consumer to finish cancellation.
5. Observe that the key disappears from `_queues` even though the new consumer is running.

## Actual vs Expected

- **Actual:** The old consumer removes the new queue state by key, leaving a live consumer untracked and allowing duplicate consumers for the same key later.
- **Expected:** A consumer should remove a queue entry only when it is still the `QueueState` that owns that consumer.

## Logs / Screenshots

```text
baseline new_state_before_old_exit=True new_state_after_old_exit=False
```

## Additional Notes

A narrow fix can make `_run_consumer()` remove the mapping only when the current entry still belongs to that consumer's `QueueState`. It does not change idle timeout values, queue priority, or message processing policy.

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

Start with UnifiedQueueManager._cleanup_idle_queues(), _run_consumer(), and enqueue(), then trace how each QueueState is registered and cleaned up during cancellation. Reproduce the interleaving described in the issue and add regression coverage. Done means an old consumer cannot remove a newly recreated state, and the new consumer remains tracked without duplicate consumers.

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
backend, testing
issue の種類
バグ
難易度
3/5
見積もり時間
1〜2日
活発さ
静か
明瞭さ
明確に書かれている
初心者へのやさしさ
45/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。