Skip to content

Remove unused per-session channels from StreamableSession#4076

Merged
ChrisJBurns merged 14 commits intomainfrom
fix/streamable-session-lazy-channels
Mar 11, 2026
Merged

Remove unused per-session channels from StreamableSession#4076
ChrisJBurns merged 14 commits intomainfrom
fix/streamable-session-lazy-channels

Conversation

@ChrisJBurns
Copy link
Copy Markdown
Collaborator

@ChrisJBurns ChrisJBurns commented Mar 10, 2026

Summary

  • Neither the streamable HTTP proxy nor the vMCP server use per-session channels (MessageCh, ResponseCh) — both route messages through global proxy-level channels instead. Each StreamableSession was eagerly allocating two buffered channels (100 slots each, ~4 KB combined) that were never read from or written to.
  • Remove the dead fields (MessageCh, ResponseCh), methods (SendMessage, SendResponse, initChannels), and supporting infrastructure (chOnce, streamableChannelBuffer constant) entirely. This eliminates ~4 KB of wasted memory per session under churn, reducing peak heap pressure that contributed to OOMKill at 128Mi.

Ref #4062

Type of change

  • Bug fix

Test plan

  • Unit tests (task test)
  • Linting (task lint-fix)

Verified no code outside the session package references StreamableSession.MessageCh, ResponseCh, SendMessage, or SendResponse. The VMCPSession type embeds StreamableSession and also never uses the removed fields.

Does this introduce a user-facing change?

No.

Special notes for reviewers

  • The previous version of this PR lazy-initialized the channels via sync.Once. Since nothing ever calls SendMessage/SendResponse, full removal is simpler and more effective.
  • The SSE session's MessageCh and SendMessage are unaffected — those are actively used by the SSE proxy.

Generated with Claude Code

StreamableSession eagerly allocated two buffered channels (100 slots
each, ~3 KB) per session, but neither the streamable HTTP proxy nor
the vMCP server ever use per-session channels — they route through
global proxy channels instead. Under high session churn (60k+
create/delete cycles), these unused allocations contributed to
monotonic memory growth leading to OOMKill.

Channels are now nil by default and lazily allocated via sync.Once on
first SendMessage/SendResponse call. Disconnect() guards against nil
channels. No behavioral change for callers that use the channels.

Relates to #4062

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added the size/XS Extra small PR: < 100 lines changed label Mar 10, 2026
@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 10, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.72%. Comparing base (2fa4371) to head (5af8f84).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4076      +/-   ##
==========================================
+ Coverage   68.65%   68.72%   +0.07%     
==========================================
  Files         454      454              
  Lines       46051    46027      -24     
==========================================
+ Hits        31616    31634      +18     
+ Misses      11994    11953      -41     
+ Partials     2441     2440       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

   - Channels are nil after construction
   - SendMessage/SendResponse allocate both channels on first call
   - Disconnect is safe with nil channels
   - Send after Disconnect returns error
   - GetData returns zeros when channels are nil

Signed-off-by: Chris Burns <29541485+ChrisJBurns@users.noreply.github.com>
@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 10, 2026
jerm-dro
jerm-dro previously approved these changes Mar 10, 2026
Copy link
Copy Markdown
Contributor

@jerm-dro jerm-dro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised these weren't garbage collected. I wonder if this object is still being leaked somehow? Regardless, this change is definitely an improvement, so LGTM.

@github-actions github-actions bot added size/S Small PR: 100-299 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 10, 2026
…treamableSession

Neither the streamable HTTP proxy nor the vMCP server use per-session
channels — both route messages through global proxy-level channels.
Remove the dead fields and methods entirely rather than lazy-initializing
them, eliminating ~4 KB of wasted memory per session.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added size/S Small PR: 100-299 lines changed and removed size/S Small PR: 100-299 lines changed labels Mar 10, 2026
@ChrisJBurns ChrisJBurns changed the title Lazy-init StreamableSession channels to fix memory leak under session churn Remove unused per-session channels from StreamableSession Mar 10, 2026
The remaining tests only verified struct construction and a boolean
flag toggle — no meaningful behavior worth testing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/S Small PR: 100-299 lines changed labels Mar 10, 2026
@JAORMX
Copy link
Copy Markdown
Collaborator

JAORMX commented Mar 11, 2026

I think you can rebase

@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 11, 2026
@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 11, 2026
@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 11, 2026
@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 11, 2026
@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 11, 2026
@ChrisJBurns ChrisJBurns merged commit c474326 into main Mar 11, 2026
43 of 44 checks passed
@ChrisJBurns ChrisJBurns deleted the fix/streamable-session-lazy-channels branch March 11, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XS Extra small PR: < 100 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants