Skip to content

Conversation

@MaxLeiter
Copy link
Contributor

@MaxLeiter MaxLeiter commented Feb 3, 2026

What does this PR do?

Inspired by https://x.com/jarredsumner/status/2017825694731145388. Definitely not expecting to see the same 1 gb saving but its at least more correct.

Arrow functions like () => controller.abort() capture the entire lexical scope, including large request bodies. When attached to long-lived signals or timeouts, this memory cannot be reclaimed.

Using controller.abort.bind(controller) only retains a reference to the controller itself, allowing request bodies to be GC'd.

How did you verify your code works?

see (AI generated) abort-leak.test.ts. I am sure there's a better way to verify this fix, but I do not know what that way is.

related issues

There are tons of memory leak issues: #9385

Relates to: #9385

(It might not actually fix that particular issue. But the contributing bot makes me put that there)

@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2026

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
Copy link
Contributor

github-actions bot commented Feb 3, 2026

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

No duplicate PRs found

Arrow functions like `() => controller.abort()` capture the entire
lexical scope, including large request bodies. When attached to
long-lived signals or timeouts, this memory cannot be reclaimed.

Using `controller.abort.bind(controller)` only retains a reference
to the controller itself, allowing request bodies to be GC'd.

Changes:
- Add `abortAfter` and `abortAfterAny` utilities in src/util/abort.ts
- Update webfetch, websearch, and codesearch tools to use the utility
- Add integration test proving ~13MB memory savings over 500 requests

Inspired by similar fix in Claude Code that reduced memory by 1GB
in long sessions.
@MaxLeiter MaxLeiter force-pushed the fix/abort-controller-memory-leak branch from 18135d1 to 75aac32 Compare February 3, 2026 22:31
@rekram1-node
Copy link
Collaborator

/review

@rekram1-node
Copy link
Collaborator

Yeah good find, we figured we were making the same mistake somewhere haha

@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2026

lgtm

@rekram1-node rekram1-node merged commit 93e0602 into anomalyco:dev Feb 3, 2026
4 checks passed
@MaxLeiter MaxLeiter deleted the fix/abort-controller-memory-leak branch February 4, 2026 00:02
sgInnora added a commit to sgInnora/opencode that referenced this pull request Feb 4, 2026
- AsyncQueue: add close()/drain() methods, iterator exits on close
- Bash tool: use Buffer[] with 10MB ring buffer instead of unbounded string concat
- LSP client: clear diagnostics map on shutdown, cap at 5000 entries
- Bus: clear subscriptions map on instance dispose
- PTY: use Buffer[] instead of string concat for session buffer
- Process exit: call Instance.disposeAll() in main finally block

Based on official v1.1.50 which includes AbortController closure fix (PR anomalyco#12024)
Combines all 9 memory optimizations for maximum stability.

Fixes: anomalyco#10913
Related: anomalyco#10914, anomalyco#12024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants