Skip to content

node: reset libp2p HTTP streams when the request ends - #902

Open
p1c2u wants to merge 2 commits into
google:mainfrom
whiteredhouse:fix-egress-stream-cancel
Open

p1c2u wants to merge 2 commits into
google:mainfrom
whiteredhouse:fix-egress-stream-cancel

Conversation

@p1c2u

@p1c2u p1c2u commented Nov 13, 2026

Copy link
Copy Markdown

go-libp2p-http's RoundTripper uses the request context only to open the stream. After that, cancelling the request does nothing: the stream and the remote handler behind it stay open until the remote side finishes on its own. Through the egress proxy this means a client that disconnects from a long or streaming response (SSE, a streaming A2A task, a streamed completion) leaves the remote peer's handler running and the stream open.

This wraps the host passed to libp2phttp.NewTransport so that NewStream registers context.AfterFunc(ctx, stream.Reset) for the request's context, and stops it when the stream is closed or reset normally. The egress proxy and the OpenAI facade use the wrapped transport.

@p1c2u
p1c2u requested a review from aojea as a code owner November 13, 2026 16:41
@google-cla

google-cla Bot commented Nov 13, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a custom libp2p HTTP transport wrapper (newLibp2pHTTPTransport) in internal/node/libp2p_transport.go that ensures underlying libp2p streams are reset when the request context is cancelled. This prevents orphaned streams on remote handlers during long or streaming requests. The new transport is integrated into openai_facade.go and sidecar.go to replace the default libp2phttp.NewTransport. Unit tests are also added in libp2p_transport_test.go to verify stream resetting and persistence behaviors. I have no feedback to provide.

go-libp2p-http uses the request context only to open the stream. When a
caller cancels a long or streaming request through the egress proxy, the
stream and the remote handler behind it stay open until the remote side
finishes on its own.

Wrap the host passed to the transport so that each stream opened for a
request is reset when that request's context ends, and use it for the
egress proxy and the OpenAI facade.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant