44
55namespace ModelContextProtocol . AspNetCore ;
66
7- internal sealed partial class IdleTrackingBackgroundService (
8- StatefulSessionManager sessions ,
9- IOptions < HttpServerTransportOptions > options ,
10- IHostApplicationLifetime appLifetime ,
11- ILogger < IdleTrackingBackgroundService > logger ) : BackgroundService
7+ internal sealed partial class IdleTrackingBackgroundService : BackgroundService
128{
13- // Workaround for https://github.com/dotnet/runtime/issues/91121. This is fixed in .NET 9 and later.
14- private readonly ILogger _logger = logger ;
9+ private readonly StatefulSessionManager _sessions ;
10+ private readonly IOptions < HttpServerTransportOptions > _options ;
11+ private readonly IHostApplicationLifetime _appLifetime ;
12+ private readonly ILogger _logger ;
1513
16- protected override async Task ExecuteAsync ( CancellationToken stoppingToken )
14+ public IdleTrackingBackgroundService (
15+ StatefulSessionManager sessions ,
16+ IOptions < HttpServerTransportOptions > options ,
17+ IHostApplicationLifetime appLifetime ,
18+ ILogger < IdleTrackingBackgroundService > logger )
1719 {
1820 // Still run loop given infinite IdleTimeout to enforce the MaxIdleSessionCount and assist graceful shutdown.
1921 if ( options . Value . IdleTimeout != Timeout . InfiniteTimeSpan )
@@ -23,14 +25,22 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
2325
2426 ArgumentOutOfRangeException . ThrowIfLessThan ( options . Value . MaxIdleSessionCount , 0 ) ;
2527
28+ _sessions = sessions ;
29+ _options = options ;
30+ _appLifetime = appLifetime ;
31+ _logger = logger ;
32+ }
33+
34+ protected override async Task ExecuteAsync ( CancellationToken stoppingToken )
35+ {
2636 try
2737 {
28- var timeProvider = options . Value . TimeProvider ;
38+ var timeProvider = _options . Value . TimeProvider ;
2939 using var timer = new PeriodicTimer ( TimeSpan . FromSeconds ( 5 ) , timeProvider ) ;
3040
3141 while ( ! stoppingToken . IsCancellationRequested && await timer . WaitForNextTickAsync ( stoppingToken ) )
3242 {
33- await sessions . PruneIdleSessionsAsync ( stoppingToken ) ;
43+ await _sessions . PruneIdleSessionsAsync ( stoppingToken ) ;
3444 }
3545 }
3646 catch ( OperationCanceledException ) when ( stoppingToken . IsCancellationRequested )
@@ -40,15 +50,15 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
4050 {
4151 try
4252 {
43- await sessions . DisposeAllSessionsAsync ( ) ;
53+ await _sessions . DisposeAllSessionsAsync ( ) ;
4454 }
4555 finally
4656 {
4757 if ( ! stoppingToken . IsCancellationRequested )
4858 {
4959 // Something went terribly wrong. A very unexpected exception must be bubbling up, but let's ensure we also stop the application,
5060 // so that it hopefully gets looked at and restarted. This shouldn't really be reachable.
51- appLifetime . StopApplication ( ) ;
61+ _appLifetime . StopApplication ( ) ;
5262 IdleTrackingBackgroundServiceStoppedUnexpectedly ( ) ;
5363 }
5464 }
0 commit comments