perf(server): skip IdleTrackingBackgroundService timer in stateless mode (#1531)
This commit is contained in:
parent
ed19286a08
commit
a4157f310f
1 changed files with 61 additions and 0 deletions
|
|
@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Http;
|
|||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using ModelContextProtocol.AspNetCore.Tests.Utils;
|
||||
using ModelContextProtocol.Protocol;
|
||||
|
|
@ -184,6 +185,55 @@ public class HttpMcpServerBuilderExtensionsTests(ITestOutputHelper testOutputHel
|
|||
Assert.Null(options.SessionMigrationHandler);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IdleTrackingBackgroundService_DoesNotStartTimer_WhenStateless()
|
||||
{
|
||||
Builder.Services
|
||||
.AddMcpServer()
|
||||
.WithHttpTransport(options => options.Stateless = true);
|
||||
|
||||
using var app = Builder.Build();
|
||||
|
||||
var idleTrackingService = GetIdleTrackingService(app.Services);
|
||||
Assert.NotNull(idleTrackingService);
|
||||
|
||||
await idleTrackingService.StartAsync(TestContext.Current.CancellationToken);
|
||||
|
||||
// BackgroundService.ExecuteTask is only set when ExecuteAsync has been kicked off via base.StartAsync.
|
||||
// In stateless mode we early-return, so ExecuteTask should remain null.
|
||||
Assert.Null(idleTrackingService.ExecuteTask);
|
||||
|
||||
await idleTrackingService.StopAsync(TestContext.Current.CancellationToken);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IdleTrackingBackgroundService_StartsTimer_WhenStateful()
|
||||
{
|
||||
Builder.Services
|
||||
.AddMcpServer()
|
||||
.WithHttpTransport();
|
||||
|
||||
using var app = Builder.Build();
|
||||
|
||||
var idleTrackingService = GetIdleTrackingService(app.Services);
|
||||
Assert.NotNull(idleTrackingService);
|
||||
|
||||
await idleTrackingService.StartAsync(TestContext.Current.CancellationToken);
|
||||
|
||||
// In the default (stateful) mode the timer loop must start, so ExecuteTask should be set.
|
||||
Assert.NotNull(idleTrackingService.ExecuteTask);
|
||||
|
||||
await idleTrackingService.StopAsync(TestContext.Current.CancellationToken);
|
||||
}
|
||||
|
||||
private static BackgroundService? GetIdleTrackingService(IServiceProvider services)
|
||||
{
|
||||
// IdleTrackingBackgroundService is internal, so look it up by type name from the registered IHostedService instances.
|
||||
return services.GetServices<IHostedService>()
|
||||
.OfType<BackgroundService>()
|
||||
.FirstOrDefault(s => s.GetType().Name == "IdleTrackingBackgroundService");
|
||||
}
|
||||
|
||||
private sealed class StubSessionMigrationHandler : ISessionMigrationHandler
|
||||
{
|
||||
public ValueTask<InitializeRequestParams?> AllowSessionMigrationAsync(
|
||||
|
|
|
|||
Loading…
Reference in a new issue