Replies: 1 comment 1 reply
-
|
Thanks -- it sounds like you've found a bug: do you want to move this to an issue? |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Pre-submission Checklist
Question Category
Your Question
Description
I have observed a potential issue with goroutine leaks in the
streamableClientConnimplementation when handling Server-Sent Events (SSE). Below is a description of the issue and the potential scenario that may lead to a goroutine leak.go-sdk/mcp/streamable.go
Lines 751 to 770 in c037ba5
Problem Scenario
When the server sends SSE events, a goroutine is spawned to read events and write them to the
s.incomingchannel:Read()as the Sole Consumer:The
Read()method is the only consumer ofs.incoming. IfRead()exits (due to s.done being closed byClose()), there will be no remaining consumer fors.incoming.If
s.incomingbecomes full (due to slow consumption or high-frequency events), the goroutine writing tos.incomingwill block and will not be able to proceed.Close()Function Call:After
Close()is called,s.doneis closed, which causes the goroutine runninghandleSSEto exit. However, the sub-goroutine writing tos.incomingremains blocked because the channel is full. Sinceresp.Body.Close()is deferred inhandleSSE, it is executed when thehandleSSEgoroutine exits, which leads to the closure of the underlying stream.Although
resp.Body.Close()will cause thefor rangeloop inside the goroutine to end when it completes a single iteration, the goroutine remains blocked ats.incoming <- evt.datawithin the loop. This prevents the goroutine from proceeding to the next iteration and exiting, thus causing the goroutine to remain in a blocked state, leading to a potential goroutine leak.Proposed Solution:
To resolve this issue, I suggest implementing a solution where the child goroutine listens for both the
donechannel and thes.incomingchannel, ensuring that the goroutine exits if either thedonechannel is closed or if there is a potential blockage on thes.incomingchannel.I am concerned that this could lead to unbounded goroutine accumulation, especially in high-load scenarios.
If I have misunderstood the behavior or missed any important context, I sincerely apologize for any confusion this might cause, and I would be grateful for further clarification. I’m happy to help address this issue if needed and contribute to improving the implementation.
Beta Was this translation helpful? Give feedback.
All reactions