diff --git a/Frends.SFTP.DownloadFiles/CHANGELOG.md b/Frends.SFTP.DownloadFiles/CHANGELOG.md index 5bf10d1..acb7d63 100644 --- a/Frends.SFTP.DownloadFiles/CHANGELOG.md +++ b/Frends.SFTP.DownloadFiles/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [2.14.0] - 2024-09-30 +### Fixed +- Fixed small memory leak with CancellationTokenSource by adding dispose to the end of the Task. + ## [2.13.0] - 2024-09-05 ### Fixed - Fixed issue with certain SFTP servers which did not use IsRegularFile property on files by modifying the logic to check that the file is not anything else than a regular file. diff --git a/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles.cs b/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles.cs index a4b73f1..9cdebd6 100644 --- a/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles.cs +++ b/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles.cs @@ -102,71 +102,80 @@ public static async Task DownloadFiles( { // Create a new cancellationTokenWithTimeOutSource with a timeout using var timeoutCts = new CancellationTokenSource(); + CancellationTokenSource linkedCts = null; if (options.Timeout > 0) { timeoutCts.CancelAfter(TimeSpan.FromSeconds(options.Timeout)); // Create a linked token source that combines the external and timeout tokens - var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token); + linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token); // Get the linked token cancellationToken = linkedCts.Token; } - var maxLogEntries = options.OperationLog ? (int?)null : 100; - var transferSink = new TransferLogSink(maxLogEntries); - var operationsLogger = new LoggerConfiguration() - .MinimumLevel.Debug() - .WriteTo.Sink(transferSink) - .CreateLogger(); - Log.Logger ??= new LoggerConfiguration() - .MinimumLevel - .Debug() - .CreateLogger(); - var fileTransferLog = Log.Logger; - - using var logger = InitializeSFTPLogger(operationsLogger); - if (string.IsNullOrEmpty(info.ProcessUri)) - fileTransferLog.Warning("ProcessUri is empty. This means the transfer view cannot link to the correct page."); - - if (!Guid.TryParse(info.TaskExecutionID, out Guid executionId)) + try { - fileTransferLog.Warning("'{0}' is not a valid task execution ID, will default to random Guid.", info.TaskExecutionID); - executionId = Guid.NewGuid(); - } + var maxLogEntries = options.OperationLog ? (int?)null : 100; + var transferSink = new TransferLogSink(maxLogEntries); + var operationsLogger = new LoggerConfiguration() + .MinimumLevel.Debug() + .WriteTo.Sink(transferSink) + .CreateLogger(); + Log.Logger ??= new LoggerConfiguration() + .MinimumLevel + .Debug() + .CreateLogger(); + var fileTransferLog = Log.Logger; + + using var logger = InitializeSFTPLogger(operationsLogger); + if (string.IsNullOrEmpty(info.ProcessUri)) + fileTransferLog.Warning("ProcessUri is empty. This means the transfer view cannot link to the correct page."); + + if (!Guid.TryParse(info.TaskExecutionID, out Guid executionId)) + { + fileTransferLog.Warning("'{0}' is not a valid task execution ID, will default to random Guid.", info.TaskExecutionID); + executionId = Guid.NewGuid(); + } - _batchContext = new BatchContext - { - Info = info, - TempWorkDir = InitializeTemporaryWorkPath(info.WorkDir), - Options = options, - InstanceId = executionId, - ServiceId = info.TransferName, - SourceFiles = new List(), - DestinationFiles = new List(), - RoutineUri = info.ProcessUri, - BatchTransferStartTime = DateTime.Now, - Source = source, - Destination = destination, - Connection = connection, - }; - - var fileTransporter = new FileTransporter(logger, _batchContext, executionId); - var result = await fileTransporter.Run(cancellationToken); - - if (options.ThrowErrorOnFail && !result.Success) - { - throw new Exception($"SFTP transfer failed: {result.UserResultMessage}. " + - $"Latest operations: \n{GetLogLines(transferSink.GetBufferedLogMessages())}."); - } + _batchContext = new BatchContext + { + Info = info, + TempWorkDir = InitializeTemporaryWorkPath(info.WorkDir), + Options = options, + InstanceId = executionId, + ServiceId = info.TransferName, + SourceFiles = new List(), + DestinationFiles = new List(), + RoutineUri = info.ProcessUri, + BatchTransferStartTime = DateTime.Now, + Source = source, + Destination = destination, + Connection = connection, + }; + + var fileTransporter = new FileTransporter(logger, _batchContext, executionId); + var result = await fileTransporter.Run(cancellationToken); + + if (options.ThrowErrorOnFail && !result.Success) + { + throw new Exception($"SFTP transfer failed: {result.UserResultMessage}. " + + $"Latest operations: \n{GetLogLines(transferSink.GetBufferedLogMessages())}."); + } - if (result.OperationsLog == null) - result.OperationsLog = new Dictionary(); - else if (options.OperationLog) - result.OperationsLog = GetLogDictionary(transferSink.GetBufferedLogMessages()); + if (result.OperationsLog == null) + result.OperationsLog = new Dictionary(); + else if (options.OperationLog) + result.OperationsLog = GetLogDictionary(transferSink.GetBufferedLogMessages()); - return new Result(result); + return new Result(result); + } + finally + { + if (linkedCts != null) + linkedCts.Dispose(); + } } private static string InitializeTemporaryWorkPath(string workDir) diff --git a/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles.csproj b/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles.csproj index eca2fe0..4ad8efd 100644 --- a/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles.csproj +++ b/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles/Frends.SFTP.DownloadFiles.csproj @@ -8,7 +8,7 @@ Frends.SFTP.DownloadFiles Frends.SFTP.DownloadFiles - 2.13.0 + 2.14.0 Frends Frends Frends