Skip to content

Commit afe100c

Browse files
committed
Address more PR feedback
1 parent d055517 commit afe100c

6 files changed

Lines changed: 43 additions & 28 deletions

File tree

src/ModelContextProtocol/Client/McpClient.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,18 @@ public override async ValueTask DisposeUnsynchronizedAsync()
148148
await _connectCts.CancelAsync().ConfigureAwait(false);
149149
}
150150

151-
await base.DisposeUnsynchronizedAsync().ConfigureAwait(false);
152-
153-
if (_sessionTransport is not null)
151+
try
154152
{
155-
await _sessionTransport.DisposeAsync().ConfigureAwait(false);
153+
await base.DisposeUnsynchronizedAsync().ConfigureAwait(false);
156154
}
155+
finally
156+
{
157+
if (_sessionTransport is not null)
158+
{
159+
await _sessionTransport.DisposeAsync().ConfigureAwait(false);
160+
}
157161

158-
_connectCts?.Dispose();
162+
_connectCts?.Dispose();
163+
}
159164
}
160165
}

src/ModelContextProtocol/Hosting/McpServerMultiSessionHostedService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ModelContextProtocol.Hosting;
99
/// <summary>
1010
/// Hosted service for a multi-session (i.e. HTTP) MCP server.
1111
/// </summary>
12-
internal class McpServerMultiSessionHostedService : BackgroundService
12+
internal sealed class McpServerMultiSessionHostedService : BackgroundService
1313
{
1414
private readonly IServerTransport _serverTransport;
1515
private readonly McpServerOptions _serverOptions;

src/ModelContextProtocol/Hosting/McpServerSingleSessionHostedService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace ModelContextProtocol.Hosting;
66
/// <summary>
77
/// Hosted service for a single-session (i.e stdio) MCP server.
88
/// </summary>
9-
internal class McpServerSingleSessionHostedService(IMcpServer session) : BackgroundService
9+
internal sealed class McpServerSingleSessionHostedService(IMcpServer session) : BackgroundService
1010
{
1111
/// <inheritdoc />
1212
protected override Task ExecuteAsync(CancellationToken stoppingToken) => session.RunAsync(stoppingToken);

src/ModelContextProtocol/Protocol/Transport/HttpListenerSseServerTransport.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public sealed class HttpListenerSseServerTransport : IServerTransport, IAsyncDis
3333
/// <param name="port">The port to listen on.</param>
3434
/// <param name="loggerFactory">A logger factory for creating loggers.</param>
3535
public HttpListenerSseServerTransport(McpServerOptions serverOptions, int port, ILoggerFactory loggerFactory)
36-
: this(serverOptions?.ServerInfo?.Name!, port, loggerFactory)
36+
: this(GetServerName(serverOptions), port, loggerFactory)
3737
{
3838
}
3939

@@ -167,4 +167,14 @@ private async Task<bool> OnMessageAsync(Stream requestStream, CancellationToken
167167
return false;
168168
}
169169
}
170+
171+
/// <summary>Validates the <paramref name="serverOptions"/> and extracts from it the server name to use.</summary>
172+
private static string GetServerName(McpServerOptions serverOptions)
173+
{
174+
Throw.IfNull(serverOptions);
175+
Throw.IfNull(serverOptions.ServerInfo);
176+
Throw.IfNull(serverOptions.ServerInfo.Name);
177+
178+
return serverOptions.ServerInfo.Name;
179+
}
170180
}

src/ModelContextProtocol/Server/McpServer.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,17 @@ public override async ValueTask DisposeUnsynchronizedAsync()
160160
tools.Changed -= _toolsChangedDelegate;
161161
}
162162

163-
await base.DisposeUnsynchronizedAsync().ConfigureAwait(false);
164-
165-
if (_serverTransport is not null && _sessionTransport is not null)
163+
try
166164
{
167-
// We created the _sessionTransport from the _serverTransport, so we own it.
168-
await _sessionTransport.DisposeAsync().ConfigureAwait(false);
165+
await base.DisposeUnsynchronizedAsync().ConfigureAwait(false);
166+
}
167+
finally
168+
{
169+
if (_serverTransport is not null && _sessionTransport is not null)
170+
{
171+
// We created the _sessionTransport from the _serverTransport, so we own it.
172+
await _sessionTransport.DisposeAsync().ConfigureAwait(false);
173+
}
169174
}
170175
}
171176

src/ModelContextProtocol/Shared/McpJsonRpcEndpoint.cs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using ModelContextProtocol.Logging;
44
using ModelContextProtocol.Protocol.Messages;
55
using ModelContextProtocol.Protocol.Transport;
6+
using ModelContextProtocol.Utils;
67
using System.Diagnostics.CodeAnalysis;
78

89
namespace ModelContextProtocol.Shared;
@@ -23,7 +24,7 @@ internal abstract class McpJsonRpcEndpoint : IAsyncDisposable
2324
private CancellationTokenSource? _sessionCts;
2425
private int _started;
2526

26-
private readonly SemaphoreSlim _disposeLock = new(1);
27+
private readonly SemaphoreSlim _disposeLock = new(1, 1);
2728
private bool _disposed;
2829

2930
protected readonly ILogger _logger;
@@ -78,21 +79,15 @@ protected void StartSession(CancellationToken fullSessionCancellationToken = def
7879

7980
public async ValueTask DisposeAsync()
8081
{
81-
await _disposeLock.WaitAsync().ConfigureAwait(false);
82-
try
83-
{
84-
if (_disposed)
85-
{
86-
return;
87-
}
88-
_disposed = true;
82+
using var _ = await _disposeLock.LockAsync().ConfigureAwait(false);
8983

90-
await DisposeUnsynchronizedAsync().ConfigureAwait(false);
91-
}
92-
finally
84+
if (_disposed)
9385
{
94-
_disposeLock.Release();
86+
return;
9587
}
88+
_disposed = true;
89+
90+
await DisposeUnsynchronizedAsync().ConfigureAwait(false);
9691
}
9792

9893
/// <summary>
@@ -126,6 +121,6 @@ public virtual async ValueTask DisposeUnsynchronizedAsync()
126121
_logger.EndpointCleanedUp(EndpointName);
127122
}
128123

129-
protected McpSession GetSessionOrThrow() =>
130-
_session ?? throw new InvalidOperationException($"This should be unreachable from public API! Call {nameof(InitializeSession)} before sending messages.");
124+
protected McpSession GetSessionOrThrow()
125+
=> _session ?? throw new InvalidOperationException($"This should be unreachable from public API! Call {nameof(InitializeSession)} before sending messages.");
131126
}

0 commit comments

Comments
 (0)