opencode icon indicating copy to clipboard operation
opencode copied to clipboard

fix(memory): Fix timeout, interval, and subscription cleanup

Open sauerdaniel opened this issue 3 days ago • 2 comments

Summary

Fix various small memory leaks from uncleaned timeouts, intervals, and event subscriptions across the codebase.

Fixes #9156

Problems

1. WebFetch Timeout (webfetch.ts)

When fetch throws an error, the timeout is not cleared.

2. Models setInterval (models.ts)

A setInterval is created but never cleared, even when the module is unloaded.

3. Bus.subscribe Return Value (github.ts)

The unsubscribe function returned by Bus.subscribe() is not captured or called.

Solution

WebFetch - Use try/finally

const timeout = setTimeout(...)
try {
  const response = await fetch(...)
  return response
} finally {
  clearTimeout(timeout)
}

Models - Track interval for cleanup

const intervalId = setInterval(...)
process.on("exit", () => clearInterval(intervalId))

Bus.subscribe - Capture unsubscribe

Store the unsubscribe function for later cleanup.

Changes

  • packages/opencode/src/util/webfetch.ts - Clear timeout in finally block
  • packages/opencode/src/provider/models.ts - Add interval cleanup on exit
  • packages/opencode/src/github/github.ts - Capture Bus.subscribe return value

Testing

  • [x] TypeScript compilation passes (bun turbo typecheck)
  • [x] Unit tests pass (725 tests, 0 failures)

Note: Manual testing of timeout/interval cleanup requires runtime verification which was not performed.

sauerdaniel avatar Jan 17 '26 23:01 sauerdaniel

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

github-actions[bot] avatar Jan 17 '26 23:01 github-actions[bot]

The following comment was made by an LLM, it may be inaccurate:

Potential Related PRs Found:

  1. #9147 - "fix(memory): Fix event listener leaks in TUI and Slack bot"

    • Related memory cleanup fix, likely part of same cleanup initiative
  2. #9146 - "fix(acp): Fix memory leak in session event streams"

    • Related memory leak fix in event streams
  3. #9145 - "fix(mcp): Fix memory leaks in OAuth transport and process cleanup"

    • Related memory leak fixes across the codebase
  4. #7914 - "fix(core): add dispose functions to prevent subscription memory leaks"

    • Addresses subscription cleanup similar to PR #9148's Bus.subscribe fix
  5. #7032 - "fix(core): add dispose functions to prevent subscription memory leaks"

    • Previous attempt at addressing subscription memory leaks
  6. #5350 - "Add timeout for file watcher subscribe to address hangs on Rosetta x86 emulation"

    • Related to timeout handling

These appear to be part of a broader memory leak cleanup effort (related to issue #5363 mentioned in the PR). PRs #9145, #9146, and #9147 are particularly close in scope and timing, suggesting they may be related fixes across different modules. Consider checking if any of these address the same files or can be consolidated.

github-actions[bot] avatar Jan 17 '26 23:01 github-actions[bot]