[PR #7043] fix: wire up ACP agent cleanup on connection end to prevent memory leaks #12221

Closed
opened 2026-02-16 18:17:08 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/7043

State: closed
Merged: No


Summary

This PR wires up cleanup to be called when ACP connections end, ensuring memory is properly freed.

Problem

When an ACP connection ends (e.g., IDE closes, client disconnects):

  • Event subscription loops (for await in setupEventSubscriptions) run forever
  • Session state in ACPSessionManager.sessions Map accumulates indefinitely
  • sessionAbortControllers never get cleaned up

This leads to the memory leak crashes reported in #4315 and #5363.

Solution

  1. ACP.Agent.dispose() - New method that:

    • Aborts all active event subscriptions via AbortController
    • Clears all session state from the session manager
    • Logs cleanup for debugging
  2. AbortController pattern in setupEventSubscriptions() - Each session's event subscription loop now:

    • Has an associated AbortController
    • Checks controller.signal.aborted in the loop
    • Cleans up controller reference in finally block
    • Handles errors gracefully during abort
  3. Cleanup wired to connection lifecycle - In acp.ts command:

    • Agent instance is captured when created
    • agent.dispose() is called after stdin ends
    • Ensures cleanup happens even on unexpected disconnection

Changes

File Change
src/acp/agent.ts Add dispose(), cleanupSession(), AbortController pattern
src/acp/session.ts Add remove(), size(), sessionIds(), clear() methods
src/cli/cmd/acp.ts Capture agent instance and call dispose() on connection end
test/acp/session.test.ts Tests for session manager cleanup methods

Testing

  • 5 tests added for ACPSessionManager
  • All tests pass
  • Typecheck passes
  • Build passes

Related Issues

  • #4315 - Memory stays unbounded: ACP session map + compacted tool outputs
  • #5363 - opencode eating 70gb of memory?

Related PRs

  • #6682 - FileTime session cleanup (by @elithrar)
  • #7032 - Bus subscription cleanup (dispose methods for Share, ShareNext, Format, Plugin)
**Original Pull Request:** https://github.com/anomalyco/opencode/pull/7043 **State:** closed **Merged:** No --- ## Summary This PR wires up cleanup to be called when ACP connections end, ensuring memory is properly freed. ## Problem When an ACP connection ends (e.g., IDE closes, client disconnects): - Event subscription loops (`for await` in `setupEventSubscriptions`) run forever - Session state in `ACPSessionManager.sessions` Map accumulates indefinitely - `sessionAbortControllers` never get cleaned up This leads to the memory leak crashes reported in #4315 and #5363. ## Solution 1. **ACP.Agent.dispose()** - New method that: - Aborts all active event subscriptions via AbortController - Clears all session state from the session manager - Logs cleanup for debugging 2. **AbortController pattern in setupEventSubscriptions()** - Each session's event subscription loop now: - Has an associated AbortController - Checks `controller.signal.aborted` in the loop - Cleans up controller reference in `finally` block - Handles errors gracefully during abort 3. **Cleanup wired to connection lifecycle** - In `acp.ts` command: - Agent instance is captured when created - `agent.dispose()` is called after stdin ends - Ensures cleanup happens even on unexpected disconnection ## Changes | File | Change | |------|--------| | `src/acp/agent.ts` | Add `dispose()`, `cleanupSession()`, AbortController pattern | | `src/acp/session.ts` | Add `remove()`, `size()`, `sessionIds()`, `clear()` methods | | `src/cli/cmd/acp.ts` | Capture agent instance and call `dispose()` on connection end | | `test/acp/session.test.ts` | Tests for session manager cleanup methods | ## Testing - 5 tests added for ACPSessionManager - All tests pass - Typecheck passes - Build passes ## Related Issues - #4315 - Memory stays unbounded: ACP session map + compacted tool outputs - #5363 - opencode eating 70gb of memory? ## Related PRs - #6682 - FileTime session cleanup (by @elithrar) - #7032 - Bus subscription cleanup (dispose methods for Share, ShareNext, Format, Plugin)
yindo added the pull-request label 2026-02-16 18:17:08 -05:00
yindo closed this issue 2026-02-16 18:17:09 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#12221