mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix(honcho): network-hermetic unit tests + lazy async writer start
Re-port of PR #67576: - plugins/memory/honcho/session.py: start the async writer thread lazily on first enqueue via _ensure_async_writer (idempotent, lock-guarded) instead of eagerly in __init__; shutdown tolerates a never-started thread - tests/honcho_plugin/conftest.py: package-wide socket guard so no honcho unit test can reach a live server - tests/honcho_plugin/test_network_isolation.py: regression tests - test_async_memory.py / test_oauth_flow.py: rebased hunks onto the pruned suite (pruned tests not resurrected) Salvaged-from: #67576 Co-authored-by: eapwrk <eapwrk@gmail.com>
This commit is contained in:
parent
8d009e4f3e
commit
bd1a850fa2
5 changed files with 356 additions and 45 deletions
|
|
@ -140,17 +140,16 @@ class HonchoSessionManager:
|
|||
config.dialectic_max_input_chars if config else 10000
|
||||
)
|
||||
|
||||
# Async write queue — started lazily on first enqueue
|
||||
# Async write queue — the writer thread starts lazily on first enqueue
|
||||
# (see _ensure_async_writer). Constructing a manager must not spawn
|
||||
# background work or touch the network: unit tests build managers with
|
||||
# mocked clients, and an eagerly-started writer raced ahead of the mock
|
||||
# and wrote test messages to a live local Honcho.
|
||||
self._async_queue: queue.Queue | None = None
|
||||
self._async_thread: threading.Thread | None = None
|
||||
self._async_thread_lock = threading.Lock()
|
||||
if write_frequency == "async":
|
||||
self._async_queue = queue.Queue()
|
||||
self._async_thread = threading.Thread(
|
||||
target=self._async_writer_loop,
|
||||
name="honcho-async-writer",
|
||||
daemon=True,
|
||||
)
|
||||
self._async_thread.start()
|
||||
|
||||
@property
|
||||
def honcho(self) -> Honcho:
|
||||
|
|
@ -511,6 +510,7 @@ class HonchoSessionManager:
|
|||
|
||||
if wf == "async":
|
||||
if self._async_queue is not None:
|
||||
self._ensure_async_writer()
|
||||
self._async_queue.put(session)
|
||||
elif wf == "turn":
|
||||
self._flush_session(session)
|
||||
|
|
@ -545,12 +545,26 @@ class HonchoSessionManager:
|
|||
except queue.Empty:
|
||||
break
|
||||
|
||||
def _ensure_async_writer(self) -> None:
|
||||
"""Start the async writer on first enqueue (idempotent, thread-safe)."""
|
||||
if self._async_thread is not None and self._async_thread.is_alive():
|
||||
return
|
||||
with self._async_thread_lock:
|
||||
if self._async_thread is None or not self._async_thread.is_alive():
|
||||
self._async_thread = threading.Thread(
|
||||
target=self._async_writer_loop,
|
||||
name="honcho-async-writer",
|
||||
daemon=True,
|
||||
)
|
||||
self._async_thread.start()
|
||||
|
||||
def shutdown(self) -> None:
|
||||
"""Gracefully shut down the async writer thread."""
|
||||
if self._async_queue is not None and self._async_thread is not None:
|
||||
if self._async_queue is not None:
|
||||
self.flush_all()
|
||||
self._async_queue.put(_ASYNC_SHUTDOWN)
|
||||
self._async_thread.join(timeout=10)
|
||||
if self._async_thread is not None and self._async_thread.is_alive():
|
||||
self._async_queue.put(_ASYNC_SHUTDOWN)
|
||||
self._async_thread.join(timeout=10)
|
||||
|
||||
def delete(self, key: str) -> bool:
|
||||
"""Delete a session from local cache."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue