Fix CancellationTokenSource resource leaks (BLOCKER severity)

- ManagedHttpDispatcher: Dispose quickFailCts and linkedTokenSource in finally block
- CommandExecutor: Dispose _cancellationTokenSource on shutdown
- Scheduler: Dispose _cancellationTokenSource on shutdown
- IntegrationTestBase: Store CTS as field and dispose in TearDown

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
admin 2025-12-19 09:35:35 -06:00
parent e2b2227a17
commit 0dc6442986
4 changed files with 17 additions and 4 deletions

View file

@ -280,6 +280,8 @@ private async ValueTask<Stream> onConnect(SocketsHttpConnectionContext context,
// This issue is being tracked at https://github.com/dotnet/runtime/issues/26177 and expected to be fixed in .NET 6.
if (useIPv6)
{
CancellationTokenSource quickFailCts = null;
CancellationTokenSource linkedTokenSource = null;
try
{
var localToken = cancellationToken;
@ -287,8 +289,8 @@ private async ValueTask<Stream> onConnect(SocketsHttpConnectionContext context,
if (!hasResolvedIPv6Availability)
{
// to make things move fast, use a very low timeout for the initial ipv6 attempt.
var quickFailCts = new CancellationTokenSource(connection_establish_timeout);
var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, quickFailCts.Token);
quickFailCts = new CancellationTokenSource(connection_establish_timeout);
linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, quickFailCts.Token);
localToken = linkedTokenSource.Token;
}
@ -305,6 +307,8 @@ private async ValueTask<Stream> onConnect(SocketsHttpConnectionContext context,
finally
{
hasResolvedIPv6Availability = true;
linkedTokenSource?.Dispose();
quickFailCts?.Dispose();
}
}

View file

@ -65,6 +65,7 @@ public void Handle(ApplicationShutdownRequested message)
{
_logger.Info("Shutting down scheduler");
_cancellationTokenSource.Cancel(true);
_cancellationTokenSource.Dispose();
Timer.Stop();
}
}

View file

@ -147,6 +147,7 @@ public void Handle(ApplicationShutdownRequested message)
{
_logger.Info("Shutting down task execution");
_cancellationTokenSource.Cancel(true);
_cancellationTokenSource.Dispose();
}
}
}

View file

@ -60,6 +60,7 @@ public abstract class IntegrationTestBase
private List<SignalRMessage> _signalRReceived;
private HubConnection _signalrConnection;
private CancellationTokenSource _signalrCts;
protected IEnumerable<SignalRMessage> SignalRMessages => _signalRReceived;
@ -148,6 +149,12 @@ public async Task IntegrationTearDown()
_signalRReceived = new List<SignalRMessage>();
}
if (_signalrCts != null)
{
_signalrCts.Dispose();
_signalrCts = null;
}
if (Directory.Exists(TempDirectory))
{
try
@ -174,11 +181,11 @@ protected async Task ConnectSignalR()
_signalRReceived = new List<SignalRMessage>();
_signalrConnection = new HubConnectionBuilder().WithUrl("http://localhost:7878/signalr/messages").Build();
var cts = new CancellationTokenSource();
_signalrCts = new CancellationTokenSource();
_signalrConnection.Closed += e =>
{
cts.Cancel();
_signalrCts.Cancel();
return Task.CompletedTask;
};