Skip to content

Fix #1927: fix: initialize() spawns new headless bridge without closing old one — process l#1928

Open
Memtensor-AI wants to merge 1 commit into
dev-20260615-v2.0.20from
bugfix/autodev-1927
Open

Fix #1927: fix: initialize() spawns new headless bridge without closing old one — process l#1928
Memtensor-AI wants to merge 1 commit into
dev-20260615-v2.0.20from
bugfix/autodev-1927

Conversation

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

Description

Fixes #1927: MemTensorProvider.initialize() was spawning a fresh MemosBridgeClient (and therefore a new --no-viewer Node bridge subprocess) on every call without closing the previously-referenced self._bridge, leaking ~93 MB per re-initialization. Hermes re-calls initialize() on each reconnect / new session, so orphaned bridges accumulated indefinitely — the headless-bridge reaper never collected them because their parent (Hermes dashboard / gateway) stays alive.

The fix mirrors the safe pattern already used by _reconnect_bridge() (line ~1727 of the same file): at the very top of initialize(), capture the current self._bridge, log its PID, call .close() inside contextlib.suppress(Exception) so a stuck Node subprocess never blocks re-init, and clear self._bridge before the existing creation flow runs. The fix is +19 lines in apps/memos-local-plugin/adapters/hermes/memos_provider/__init__.py, scoped entirely to the plugin sub-project; main src/memos/ is untouched and make openapi is not required.

Verification (TDD): added 3 regression tests in tests/python/test_hermes_provider_pipeline.pytest_initialize_closes_previous_bridge_before_spawning_new_one (the actual leak scenario, two queued FakeBridge instances), test_initialize_when_no_previous_bridge_does_not_call_close (first-init happy path), and test_initialize_swallows_exception_from_old_bridge_close (isolation when the previous bridge's close() raises). Tests #1 and #3 fail before the fix and pass after; full plugin Python suite is 45/45 passing. ruff check and ruff format --check both clean on the touched files.

Branch bugfix/autodev-1927 pushed to origin at commit 5a0a3fc3. Spec archive synced to memos-autodev-specs.

Related Issue (Required): Fixes #1927

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (does not change functionality, e.g. code style improvements, linting)
  • Documentation update

How Has This Been Tested?

Automated tests are pending.

  • Unit Test
  • Test Script Or Test Steps (please provide)
  • Pipeline Automated API Test (please provide)

Checklist

  • I have performed a self-review of my own code
  • I have commented my code in hard-to-understand areas
  • I have added tests that prove my fix is effective or that my feature works
  • I have created related documentation issue/PR in MemOS-Docs (if applicable)
  • I have linked the issue to this PR (if applicable)
  • I have mentioned the person who will review this PR

@MatthewZhuang, @CarltonXiang, @syzsunshine219, @World-controller please review this PR.

Reviewer Checklist

…p process leak

Hermes calls `MemTensorProvider.initialize()` on every reconnect / new
session. Each call spawned a fresh `MemosBridgeClient` (and therefore a
new `--no-viewer` Node subprocess) but never closed the previous one
referenced by `self._bridge`. The orphaned bridges accumulated at
~93 MB each, indefinitely — the headless-bridge reaper does not catch
them because their parent (Hermes dashboard / gateway) stays alive.

Close any pre-existing `self._bridge` at the top of `initialize()`,
mirroring the safe pattern already used by `_reconnect_bridge()`
(swallowing exceptions so a stuck Node subprocess never blocks
re-init). Added 3 regression tests covering: the leak scenario,
the no-previous-bridge happy path, and isolation when the old
bridge's close() raises.

Fixes #1927
@Memtensor-AI

Copy link
Copy Markdown
Collaborator Author

✅ Automated Test Results: PASSED

All tests passed (35/35 executed, 35 skipped). memos_local_plugin/smoke: 0/0, memos_local_plugin/contract: 35 passed, 35 skipped. Duration: 4s AI-generated tests: 0/17 passed.

Branch: bugfix/autodev-1927

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-generated bug Something isn't working | 功能异常

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants