fix: prevent memory leaks from SSE streams, LSP, Bus, and process cleanup#15646
fix: prevent memory leaks from SSE streams, LSP, Bus, and process cleanup#15646brendandebeasi wants to merge 1 commit intoanomalyco:devfrom
Conversation
|
The following comment was made by an LLM, it may be inaccurate: Potential duplicate/related PRs found:
These PRs all address memory leak issues in similar areas. Review #15435 and #14650 particularly to ensure the SSE stream cleanup in PR #15646 doesn't duplicate existing fixes or conflict with prior memory leak consolidation efforts. |
|
Reviewed the related PRs flagged above — this PR is complementary, not duplicative:
The core fix in this PR — awaiting |
1f990f0 to
11eef33
Compare
b2d9a19 to
66587a7
Compare
- Add cleanup() guard with done flag to prevent double-cleanup - await stream.writeSSE() calls and catch errors to trigger cleanup - Unsubscribe Bus and GlobalBus listeners on abort or write failure - Clear heartbeat interval in all exit paths - Add Bus.debug() subscription count introspection - Add GET /debug/memory endpoint for runtime memory diagnostics
66587a7 to
5788c8b
Compare
Issue for this PR
Fixes #15645
Relates to #10913, #9140, #11696, #9156, #14091, #15592
Type of change
What does this PR do?
Fixes multiple memory leaks that cause OpenCode's memory usage to grow unbounded over time, particularly during long-running sessions.
Memory leak fixes (always active)
server.ts,global.ts,routes.tsdoneflag +writeSSEerror handling + unsub on abortclient.tsdiagnostics.clear()+ resetfilesMap in shutdownbus/index.tssubscriptions.clear()after dispose callbackacp.ts.on()→.once()for end/error listenersgithub.tsfinallyblockindex.tsInstance.disposeAll()with 5s timeout beforeprocess.exit()Debug tooling (always available, zero overhead)
Bus.debug()— subscription count introspection per event typeInstance.debug()— cache state inspectionState.debug()— state entry countsGET /debug/memory— on-demand runtime memory diagnostics endpointSIGUSR1signal — captures heap snapshot + diagnostic report to~/.local/share/opencode/diagnostics/Memory monitoring (opt-in via
OPENCODE_DIAGNOSTICS=1)The polling monitor and auto-kill are disabled by default. To enable:
When enabled:
OPENCODE_MEMORY_LIMIT=Nin GB) — writes heap snapshot + diagnostic report, then exitsmax(2GB, min(25% total RAM, 4GB))How did you verify your code works?
Property 'tui' does not exist on type 'Config'— unrelated to this PR)OPENCODE_DIAGNOSTICS=1, only SIGUSR1 handler is registered (no polling, no kill)OPENCODE_DIAGNOSTICS=1, full monitoring loop activatesChecklist