-
Notifications
You must be signed in to change notification settings - Fork 5.1k
fix: wire up ACP agent cleanup on connection end to prevent memory leaks #7043
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add dispose() method to ACP.Agent that aborts all event subscriptions and clears session state - Add AbortController pattern to setupEventSubscriptions() for clean shutdown - Add cleanupSession() to abort individual session subscriptions - Wire up Agent.dispose() call when ACP command stdin closes - Add remove(), size(), sessionIds(), clear() methods to ACPSessionManager This ensures that when an ACP connection ends, all event subscription loops are properly terminated and session state is cleaned up, preventing memory accumulation during long-running ACP sessions. Related to anomalyco#4315, anomalyco#5363
|
The following comment was made by an LLM, it may be inaccurate: SummaryNo duplicate PRs found. However, PR #7043 is part of a related series: Related PRs (Not Duplicates):
Relationship:PR #7043 complements #7032 and #7039 by actually wiring up the cleanup to be called when ACP connections end, rather than just adding the cleanup methods. The three PRs form a complete solution to the memory leak issues (#4315, #5363). Conclusion: PR #7043 is the integration point that makes the previous cleanup work actually functional—not a duplicate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR addresses memory leaks in ACP agent connections by implementing a cleanup mechanism that runs when connections end. The fix adds disposal methods, introduces AbortController-based event subscription management, and wires cleanup to the connection lifecycle.
- Adds
dispose()method to the Agent class to abort event subscriptions and clear session state - Implements AbortController pattern for managing event subscription lifecycles
- Extends ACPSessionManager with cleanup methods (
remove,size,sessionIds,clear)
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
packages/opencode/src/acp/agent.ts |
Adds dispose(), cleanupSession(), AbortController tracking, and abort signal checks in event subscription loop |
packages/opencode/src/acp/session.ts |
Adds session cleanup methods for memory management |
packages/opencode/src/cli/cmd/acp.ts |
Captures agent instance and calls dispose() when stdin ends |
packages/opencode/test/acp/session.test.ts |
Adds comprehensive tests for new ACPSessionManager cleanup methods |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Addressing Review CommentsRe: break statements in finally blocks (lines 168, 372) Re: AbortController signal not passed to subscribe() Re: disposed checks in async operations |
|
Additional fix for disposed checks: Added more comprehensive
This ensures that in-flight async operations will exit gracefully rather than continuing to use potentially invalid resources. |
|
Fixed: AbortController signal now passed to subscribe() After investigating, the SDK's
Updated the code to pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
Address Copilot review comments - ensure all test SDK mocks have consistent interface with both create and get methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Closing as superseded by #7032 which now includes the ACP agent cleanup functionality (dispose method, sessionAbortControllers, cleanupSession, and connection.closed handler). The session manager utility methods (remove, size, sessionIds, clear) can be added in a follow-up PR if needed. |
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):
for awaitinsetupEventSubscriptions) run foreverACPSessionManager.sessionsMap accumulates indefinitelysessionAbortControllersnever get cleaned upThis leads to the memory leak crashes reported in #4315 and #5363.
Solution
ACP.Agent.dispose() - New method that:
AbortController pattern in setupEventSubscriptions() - Each session's event subscription loop now:
controller.signal.abortedin the loopfinallyblockCleanup wired to connection lifecycle - In
acp.tscommand:agent.dispose()is called after stdin endsChanges
src/acp/agent.tsdispose(),cleanupSession(), AbortController patternsrc/acp/session.tsremove(),size(),sessionIds(),clear()methodssrc/cli/cmd/acp.tsdispose()on connection endtest/acp/session.test.tsTesting
Related Issues
Related PRs