Skip to content

Commit 3109e85

Browse files
committed
Prevent spurious ODEs when StreamableHttpClientSessionTransport is disposed multiple times
- This is the same approach we use in McpEndpoint and SseWriter - I went for a minimal change, but I can copy this to TransportBase if we like to use it for all derived types - We could also update AutoDetectingClientSessionTransport.InitializeAsync to avoid this, but we shouldn't have to
1 parent 3bc0c7d commit 3109e85

1 file changed

Lines changed: 11 additions & 0 deletions

File tree

src/ModelContextProtocol.Core/Client/StreamableHttpClientSessionTransport.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ internal sealed partial class StreamableHttpClientSessionTransport : TransportBa
3030
private string? _negotiatedProtocolVersion;
3131
private Task? _getReceiveTask;
3232

33+
private readonly SemaphoreSlim _disposeLock = new(1, 1);
34+
private bool _disposed;
35+
3336
public StreamableHttpClientSessionTransport(
3437
string endpointName,
3538
SseClientTransportOptions transportOptions,
@@ -138,6 +141,14 @@ internal async Task<HttpResponseMessage> SendHttpRequestAsync(JsonRpcMessage mes
138141

139142
public override async ValueTask DisposeAsync()
140143
{
144+
using var _ = await _disposeLock.LockAsync().ConfigureAwait(false);
145+
146+
if (_disposed)
147+
{
148+
return;
149+
}
150+
_disposed = true;
151+
141152
try
142153
{
143154
await _connectionCts.CancelAsync().ConfigureAwait(false);

0 commit comments

Comments
 (0)