Wire session-aware backend routing in proxy transports (RC-12)#4318
Wire session-aware backend routing in proxy transports (RC-12)#4318
Conversation
There was a problem hiding this comment.
Large PR Detected
This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.
How to unblock this PR:
Add a section to your PR description with the following format:
## Large PR Justification
[Explain why this PR must be large, such as:]
- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformationAlternative:
Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.
See our Contributing Guidelines for more details.
This review will be automatically dismissed once you add the justification section.
PR size has been reduced below the XL threshold. Thank you for splitting this up!
|
✅ PR size has been reduced below the XL threshold. The size review has been dismissed and this PR can now proceed with normal review. Thank you for splitting this up! |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4318 +/- ##
==========================================
+ Coverage 69.53% 69.58% +0.05%
==========================================
Files 480 480
Lines 48641 48718 +77
==========================================
+ Hits 33823 33902 +79
+ Misses 12215 12207 -8
- Partials 2603 2609 +6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
💡 Codex ReviewIn Line 623 in a58edb9
toolhive/pkg/skills/skillsvc/skillsvc.go Line 265 in a58edb9 After resolving from registry, ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
Pull request overview
This PR implements RC-12 session-sticky routing capabilities in the proxy transports by allowing an injectable session storage backend and using session metadata in the transparent proxy to route follow-up requests back to the originating backend.
Changes:
- Add
WithSessionStorage(session.Storage)option support to the Streamable HTTP, HTTP-SSE, and Transparent proxies (and adjust constructors to accept options). - Transparent proxy now records
backend_urlin session metadata on initialize and uses it duringReverseProxy.Rewriteto steer subsequent requests. - Add/extend unit/integration tests for session storage injection and transparent backend routing behavior.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/transport/stdio.go | Updates proxy constructor calls for new middleware parameter shape; currently no plumbing for session storage injection. |
| pkg/transport/proxy/transparent/transparent_proxy.go | Adds session storage option, unknown-session guard, session metadata persistence, and Rewrite-based backend routing. |
| pkg/transport/proxy/transparent/backend_routing_test.go | New tests covering backend routing via backend_url and 400s for unknown sessions. |
| pkg/transport/proxy/transparent/transparent_test.go | Adds a unit test ensuring WithSessionStorage initializes a session manager. |
| pkg/transport/proxy/streamable/streamable_proxy.go | Introduces options pattern and WithSessionStorage for Streamable proxy; updates constructor signature. |
| pkg/transport/proxy/streamable/streamable_proxy_test.go | Updates constructor call sites and adds a WithSessionStorage unit test. |
| pkg/transport/proxy/streamable/streamable_proxy_spec_test.go | Updates constructor call sites for new signature. |
| pkg/transport/proxy/streamable/streamable_proxy_mcp_client_integration_test.go | Updates constructor call sites for new signature. |
| pkg/transport/proxy/streamable/streamable_proxy_integration_test.go | Updates constructor call sites for new signature. |
| pkg/transport/proxy/httpsse/http_proxy.go | Introduces options pattern and WithSessionStorage for HTTP-SSE proxy; updates constructor signature. |
| pkg/transport/proxy/httpsse/http_proxy_test.go | Updates constructor call sites and adds a WithSessionStorage unit test. |
| pkg/transport/proxy/httpsse/http_proxy_integration_test.go | Updates constructor call sites for new signature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 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.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…smatch The CI Go build cache is keyed on go.sum, so source-only changes do not bust it. With -coverpkg=./..., every test binary instruments all packages; if any binary was compiled from a stale cached artifact whose coverage statement count differs from the current source, go tool cover -func errors with "inconsistent NumStmt: changed from N to M". Replace go clean -testcache with go clean -cache -testcache so that both the test-result cache and the compiled artifact cache are wiped before each coverage run, guaranteeing every package is instrumented from fresh source. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds Option/WithSessionStorage functional option to the streamable HTTP proxy, enabling injection of a custom session storage backend for multi-replica deployments. Updates NewHTTPProxy signature from variadic middlewares to explicit slice + variadic opts, and fixes all call sites. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-12) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… in Rewrite (RC-12) On initialize responses that return Mcp-Session-Id, RoundTrip now creates the session via AddSession and stores backend_url=targetURI in metadata. The Rewrite closure in Start looks up that metadata to override the outbound URL, enabling session-aware routing to originating backend pods. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…wn session (RC-12) Guard added in RoundTrip: requests carrying an Mcp-Session-Id that is not found in the session store are rejected with HTTP 400 immediately, unless the request is an initialize call. Two tests added to cover both branches. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Implements RC-12 from the horizontal scaling RFC (THV-0047, epic #263):
WithSessionStorage(session.Storage) Optionto all three proxy transports (streamable, HTTP-SSE, transparent), allowing a Redis-backed session store to be injected for multi-replica deploymentsbackend_url = targetURIin session metadata when aninitializeresponse returnsMcp-Session-Id, and routes subsequent requests to the originating pod via theRewriteclosureFixes #4212
Type of change
Test plan
task test)task test-e2e)task lint-fix)Changes
Does this introduce a user-facing change?
Special notes for reviewers
Large PR Justification
This is a complete PR with an isolated functionality and complete tests. Cannot be split.