Skip to content

fix(honcho): fully shut down async writer + close HTTP client on exit - #7627

Open
btcjon wants to merge 1 commit into
NousResearch:mainfrom
btcjon:fix/honcho-shutdown-http-close
Open

fix(honcho): fully shut down async writer + close HTTP client on exit#7627
btcjon wants to merge 1 commit into
NousResearch:mainfrom
btcjon:fix/honcho-shutdown-http-close

Conversation

@btcjon

@btcjon btcjon commented Apr 11, 2026

Copy link
Copy Markdown

Problem

HonchoMemoryProvider.shutdown() only called flush_all(), which leaves two things alive at interpreter teardown:

  1. The honcho-async-writer background thread (owned by HonchoSessionManager) — flush_all() drains the queue but never sends _ASYNC_SHUTDOWN and never joins the thread.
  2. The underlying httpx.Client inside the Honcho SDK (honcho._http._client) — its connection pool is still open when Python finalizes.

This race caused intermittent crashes during clean exit.

Fix

HonchoMemoryProvider.shutdown() now:

  1. Calls HonchoSessionManager.shutdown() (which already does flush → _ASYNC_SHUTDOWNjoin).
  2. Explicitly closes honcho._http so the httpx pool is torn down before finalization.

Both wrapped in try/except with debug logging — shutdown must never raise.

Verification

Offline smoke test with a mocked Honcho client:

async thread: <Thread(honcho-async-writer, started daemon ...)>
alive before: True
alive after : False
http.close called: True

Full honcho test suite: 141 passed, 3 skipped.

Sibling memory plugins (byterover, hindsight, holographic) were audited for the same pattern — none affected. supermemory is not installed in this environment.

HonchoMemoryProvider.shutdown() only called flush_all(), which left the
async writer thread alive and the underlying httpx connection pool open.
At interpreter teardown this race caused intermittent crashes.

Now calls HonchoSessionManager.shutdown() (flush + _ASYNC_SHUTDOWN +
join) and explicitly closes honcho._http so the httpx pool is torn down
before Python finalization.
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint labels Apr 29, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing deterministic Honcho teardown. The current provider still calls only flush_all() at plugins/memory/honcho/__init__.py:1421, while HonchoSessionManager.shutdown() owns the async-writer sentinel and join at plugins/memory/honcho/session.py:548-553, so the underlying target is real.

Problems

  • The replacement at this PR's right-side line 707 regresses writeFrequency: "session": HonchoSessionManager.shutdown() only calls flush_all() when an async queue/thread exists (plugins/memory/honcho/session.py:550-553), but session mode has no queue and intentionally defers writes to flush_all() (plugins/memory/honcho/session.py:517-519). Preserve the provider's final flush for every mode.
  • This one-file PR adds no regression tests. Existing tests cover manager async shutdown (tests/honcho_plugin/test_async_memory.py:291-336), not provider shutdown or the private client._http.close() path.
  • The unchanged 5-second provider prefetch join (plugins/memory/honcho/__init__.py:1415-1417) remains relevant to the timeout mismatch documented by cross-referenced issue #33485.

Suggested changes

  • Move the universal flush into HonchoSessionManager.shutdown() before its async-worker conditional, then test session-mode flush, writer termination, and idempotent HTTP close.
  • Reconcile the prefetch-thread join with #33485 before closing the shared client.

Automated hermes-sweeper review.

except Exception:
pass
self._manager.shutdown()
except Exception as e:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HonchoSessionManager.shutdown() currently invokes flush_all() only when an async queue/thread exists (plugins/memory/honcho/session.py:550-553). For supported writeFrequency: "session", no queue exists and writes defer until flush_all() (session.py:517-519), so this replacement removes the provider's final flush. Make manager shutdown flush all modes unconditionally, or retain that flush here before invoking the worker teardown.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users area/memory Memory subsystem: store, providers, sync, background reviews labels Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/memory Memory subsystem: store, providers, sync, background reviews comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants