public void Dispose() { if (_downloadedFiles > 0) { ExecutionLogger.Output(StringUtil.Loc("RMDownloadComplete")); } LogStatistics(); }
private void LogStatistics() { ExecutionLogger.Output(StringUtil.Loc("RMDownloadProgress", _totalFiles, _downloadedFiles, _newEmptyFiles)); if (_downloadedFiles > 0) { string message = StringUtil.Loc("RMDownloadProgressDetails", Math.Ceiling(_bytesDownloaded / (1024.0 * 1024.0)), Math.Floor(_bytesDownloaded / (1024.0 * _elapsedDownloadTime.TotalSeconds)), _elapsedDownloadTime); ExecutionLogger.Output(message); } }
protected virtual void Dispose(bool disposing) { if (disposing) { if (_downloadedFiles > 0) { ExecutionLogger.Output(StringUtil.Loc("RMDownloadComplete")); } LogStatistics(); } }
private async Task DownloadItemImplAsync( SemaphoreSlim downloadThrottle, ContainerItem ticketedItem, string downloadPath, CancellationToken cancellationToken) { try { lock (_lock) { ExecutionLogger.Debug(StringUtil.Format("Acquiring semaphore to download file {0}", downloadPath)); } await downloadThrottle.WaitAsync().ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { return; } // Download the file content to a temp file on the same drive. // Assumption: the build won't produce files ending in .download. string tmpDownloadPath = downloadPath + ".download"; FileSystemManager.EnsureParentDirectory(tmpDownloadPath); FileSystemManager.DeleteFile(downloadPath); lock (_lock) { ExecutionLogger.Output(StringUtil.Loc("RMDownloadStartDownloadOfFile", downloadPath)); } await GetFileAsync(ticketedItem, tmpDownloadPath, cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { return; } // With the content successfully downloaded, move the tmp file to its permanent location. FileSystemManager.MoveFile(tmpDownloadPath, downloadPath); } finally { downloadThrottle.Release(); } }
private async Task LogProgressAsync(LinkedList <Task> remainingTasks) { Stopwatch watch = Stopwatch.StartNew(); // Log progress until all downloads complete while (remainingTasks.Any()) { Task delayTask = Task.Delay(ProgressInterval); if (remainingTasks.Count < 20) { // temporarily add the delay task. remainingTasks.AddLast(delayTask); // wait for the delay task or a download to complete. // Task.WhenAny is probably an O(n) operation, so we only do this if there's not many downloads remaining. await Task.WhenAny(remainingTasks).ConfigureAwait(false); // remove the delay task. remainingTasks.RemoveLast(); } else { // go do something else for 5 seconds. await delayTask.ConfigureAwait(false); } // remove any download tasks that completed. LinkedListNode <Task> task = remainingTasks.First; while (task != null) { LinkedListNode <Task> nextTask = task.Next; if (task.Value.IsCompleted) { // don't wait to throw for faulted tasks. await task.Value.ConfigureAwait(false); remainingTasks.Remove(task); } task = nextTask; } // check how many downloads remain. if (remainingTasks.Count > 0) { if (watch.Elapsed > ProgressInterval) { ExecutionLogger.Output(StringUtil.Loc("RMRemainingDownloads", remainingTasks.Count)); watch.Restart(); } if (remainingTasks.Count != _previousRemainingTaskCount) { _lastTaskCompletionTime = DateTime.UtcNow; _previousRemainingTaskCount = remainingTasks.Count; } TimeSpan timeSinceLastTaskCompletion = DateTime.UtcNow - _lastTaskCompletionTime; TimeSpan timeSinceLastDiag = DateTime.UtcNow - _lastTaskDiagTime; if (timeSinceLastTaskCompletion > TaskDiagThreshold && timeSinceLastDiag > TaskDiagThreshold) { var taskStates = remainingTasks.GroupBy(dt => dt.Status); lock (_lock) { ExecutionLogger.Warning(StringUtil.Loc("RMDownloadTaskCompletedStatus", (int)timeSinceLastTaskCompletion.TotalMinutes)); foreach (IGrouping <TaskStatus, Task> group in taskStates) { ExecutionLogger.Warning(StringUtil.Loc("RMDownloadTaskStates", group.Key, group.Count())); } } _lastTaskDiagTime = DateTime.UtcNow; } } } }