deerflow2/backend/packages/harness/deerflow/agents/memory
DanielWalnut 8760937439
fix(memory): use asyncio.to_thread for blocking file I/O in aupdate_memory (#2220)
* fix(memory): use asyncio.to_thread for blocking file I/O in aupdate_memory

`_finalize_update` performs synchronous blocking operations (os.mkdir,
file open/write/rename/stat) that were called directly from the async
`aupdate_memory` method, causing `BlockingError` from blockbuster when
running under an ASGI server. Wrap the call with `asyncio.to_thread` to
offload all blocking I/O to a thread pool.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(memory): use unique temp filename to prevent concurrent write collision

`file_path.with_suffix(".tmp")` produces a fixed path — concurrent saves
for the same agent (now possible after wrapping _finalize_update in
asyncio.to_thread) would clobber the same temp file. Use a UUID-suffixed
temp file so each write is isolated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(memory): also offload _prepare_update_prompt to thread pool

FileMemoryStorage.load() inside _prepare_update_prompt performs
synchronous stat() and file read, blocking the event loop just like
_finalize_update did. Wrap _prepare_update_prompt in asyncio.to_thread
for the same reason.

The async path now has no blocking file I/O on the event loop:
  to_thread(_prepare_update_prompt) → await model.ainvoke() → to_thread(_finalize_update)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 16:41:54 +08:00
..
__init__.py feat: add memory management actions and local filters in memory settings (#1467) 2026-03-29 13:14:45 +08:00
message_processing.py feat: flush memory before summarization (#2176) 2026-04-14 15:01:06 +08:00
prompt.py fix: inject longTermBackground into memory prompt (#1734) 2026-04-03 11:21:58 +08:00
queue.py feat: flush memory before summarization (#2176) 2026-04-14 15:01:06 +08:00
storage.py fix(memory): use asyncio.to_thread for blocking file I/O in aupdate_memory (#2220) 2026-04-14 16:41:54 +08:00
summarization_hook.py feat: flush memory before summarization (#2176) 2026-04-14 15:01:06 +08:00
updater.py fix(memory): use asyncio.to_thread for blocking file I/O in aupdate_memory (#2220) 2026-04-14 16:41:54 +08:00