fix(memory): scope queue merge key to (thread_id, agent_name) and skip idle reschedule#2592
Open
octo-patch wants to merge 1 commit intobytedance:mainfrom
Open
Conversation
…p idle reschedule Fixes bytedance#2547: _enqueue_locked used thread_id alone as the deduplication key, causing updates from different agents on the same thread to overwrite each other. The merge key is now (thread_id, agent_name) so per-agent pending entries are kept separate. Fixes bytedance#2548: _process_queue unconditionally scheduled a zero-delay timer when _processing was already True, spinning idle wakeups even when the queue was empty. The reschedule now only fires when there is pending work. Co-Authored-By: Octopus <liyuan851277048@icloud.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes memory update queue behavior when multiple agents enqueue updates for the same thread, and reduces unnecessary zero-delay rescheduling while processing is already active.
Changes:
- Scope queue deduplication/merge behavior to
(thread_id, agent_name)instead of justthread_id. - Avoid rescheduling an immediate (0s) timer from
_process_queuewhen already processing and there’s no pending work. - Update/add tests to cover multi-agent enqueue behavior and the “busy + empty queue” no-reschedule case.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
backend/packages/harness/deerflow/agents/memory/queue.py |
Adjusts merge key to include agent_name and adds a busy-guard to skip idle reschedules. |
backend/tests/test_memory_queue.py |
Updates queue tests for the new keying behavior and adds coverage for the busy-guard branches. |
Comment on lines
151
to
157
| with self._lock: | ||
| if self._processing: | ||
| # Preserve immediate flush semantics even if another worker is active. | ||
| self._schedule_timer(0) | ||
| # Only reschedule if there is pending work; avoids spinning zero-delay | ||
| # timers when add_nowait/flush_nowait fire while the worker is busy. | ||
| if self._queue: | ||
| self._schedule_timer(0) | ||
| return |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2547
Fixes #2548
Problem
Issue #2547 — wrong merge key in memory queue
_enqueue_lockedmatched pending queue entries bythread_idalone. When two agents ran on the same thread and both calledadd()before the debounce fired, the second call silently replaced the first, dropping the first agent's conversation from the pending batch.Issue #2548 — zero-delay timer spin when busy
_process_queuealways called_schedule_timer(0)when_processingwasTrue, even if the queue was empty. Repeated calls toadd_nowaitorflush_nowaitduring an active processing run would each create a new zero-delay timer, causing unnecessary wakeups and scheduling overhead.Solution
#2547: Changed the deduplication key from
thread_idto(thread_id, agent_name). Entries for different agents on the same thread are now kept as separate queue items and processed independently.#2548: Added a guard in
_process_queueso the follow-up zero-delay timer is only scheduled whenself._queueactually contains pending work. No-op reschedules no longer occur.Testing
Updated
test_memory_queue.py:test_process_queue_reschedules_immediately_when_already_processingwith two focused tests covering the with-work and no-work branches of the busy-guard.test_enqueue_two_agents_same_thread_stored_independentlyto verify the new (thread_id, agent_name) key keeps separate entries.test_enqueue_same_agent_same_thread_mergesto confirm same-agent deduplication still works.All 11 tests pass (
uv run pytest tests/test_memory_queue.py -v).