Skip to content

fix(memory): close embedded Hindsight async client cleanly (salvage #14605)#16209

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-d7874f79
Apr 26, 2026
Merged

fix(memory): close embedded Hindsight async client cleanly (salvage #14605)#16209
teknium1 merged 2 commits into
mainfrom
hermes/hermes-d7874f79

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

HindsightEmbedded.close() delegates to its sync client.close(). When Hermes created/used that client on the shared async loop, closing it from the main thread raises attached to a different loop before aiohttp releases the session — so the ClientSession / TCPConnector leak past provider teardown.

Fix closes the embedded inner async client on the shared loop first via _run_sync(inner_client.aclose()), then lets the wrapper's sync close() do its daemon/UI bookkeeping.

Salvage of #14605 by @maxims-oss. Original author attribution preserved via rebase merge.

Salvage note

PR was stale on the test-file anchor: TestSharedEventLoopLifecycle + TestAvailability expansions landed on main after the PR was written (file grew 612 → 1104 lines). Rebased the new TestShutdown class to append cleanly after TestSharedEventLoopLifecycle instead of in the middle. Production hunk was clean.

Changes

  • plugins/memory/hindsight/init.py shutdown() local_embedded branch: close inner async client on shared loop via _run_sync(inner_client.aclose()) then null out self._client._client before calling wrapper close().
  • tests/plugins/memory/test_hindsight_provider.py: new TestShutdown class with test_local_embedded_shutdown_closes_inner_async_client_on_shared_loop.
  • scripts/release.py: AUTHOR_MAP entry for @maxims-oss.

Validation

Before After
local_embedded shutdown sync close() → RuntimeError swallowed, session leaks inner async aclose() on shared loop → wrapper close() → clean
Targeted test passes (0.4s)
Broader hindsight suite 75 pass, 1 pre-existing uv-not-found env failure same

Closes #14605 (original PR, merged via salvage).

maxims-oss and others added 2 commits April 26, 2026 12:53
HindsightEmbedded.close() delegates to its sync client.close(). When Hermes
created/used that client on the shared async loop, closing it from the main
thread raises 'attached to a different loop' before aiohttp releases the
session — so the ClientSession / TCPConnector leak past provider teardown.

Close the embedded inner async client on the shared loop first via
_run_sync(inner_client.aclose()), then let the wrapper's sync close()
do its daemon/UI bookkeeping.

Salvage of #14605: test placement rebased — appended TestShutdown class
after TestSharedEventLoopLifecycle (which landed on main after the PR was
written). Original author attribution preserved.
@teknium1 teknium1 merged commit 822b507 into main Apr 26, 2026
10 of 11 checks passed
@teknium1 teknium1 deleted the hermes/hermes-d7874f79 branch April 26, 2026 19:54
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins tool/memory Memory tool and memory providers labels Apr 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have tool/memory Memory tool and memory providers type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants