Skip to content

Commit

Permalink
Fix downloading of large files when installing Simulators (#659)
Browse files Browse the repository at this point in the history
Also show progress and allow to turn it off via `--hide-progress`
  • Loading branch information
premun authored Jul 7, 2021
1 parent a36eef8 commit c6d444e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Microsoft.DotNet.XHarness.CLI.CommandArguments.Apple
{
internal class HideProgressArgument : SwitchArgument
{
public HideProgressArgument()
: base("hide-progress", "Won't show progress when downloading the Simulator runtime", false)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ internal class InstallCommandArguments : SimulatorsCommandArguments
{
public ForceInstallationArgument Force { get; } = new();

public HideProgressArgument HideProgress { get; } = new();

protected override IEnumerable<Argument> GetAdditionalArguments() => new Argument[]
{
Force,
HideProgress,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,60 @@ private async Task<bool> Install(Simulator simulator)
{
var watch = Stopwatch.StartNew();

using (var response = await s_client.GetAsync(simulator.Source))
using (var fileStream = File.Create(downloadPath))
using (var response = await s_client.GetAsync(simulator.Source, HttpCompletionOption.ResponseHeadersRead))
{
await response.Content.CopyToAsync(fileStream);
response.EnsureSuccessStatusCode();

using var fileStream = File.Create(downloadPath);

if (Arguments.HideProgress)
{
await response.Content.CopyToAsync(fileStream);
}
else
{
var progressMessage = $"Starting the download..";
Console.Write(progressMessage);

void ShowProgress(long totalBytesDownloaded)
{
var previousLength = progressMessage.Length;
progressMessage = $"[{watch.Elapsed:hh\\:mm\\:ss}] {totalBytesDownloaded / 1024.0 / 1024.0:N2} / {simulator.FileSize / 1024.0 / 1024.0:N2} MB\t\t{(int)(100 * totalBytesDownloaded / simulator.FileSize),3}%";
Console.Write("\r" + progressMessage.PadRight(previousLength));
}

var totalBytesDownloaded = 0L;
var buffer = new byte[8192];
var lastUpdate = DateTime.Now;
var updateFrequency = TimeSpan.FromMilliseconds(400);

using var responseStream = await response.Content.ReadAsStreamAsync();
while (true)
{
var bytesRead = await responseStream.ReadAsync(buffer);
if (bytesRead == 0)
{
Console.Write("\r" + " ".PadRight(progressMessage.Length) + "\r");
break;
}

await fileStream.WriteAsync(buffer.AsMemory(0, bytesRead));

totalBytesDownloaded += bytesRead;

if (DateTime.Now - lastUpdate > updateFrequency)
{
ShowProgress(totalBytesDownloaded);
lastUpdate = DateTime.Now;
}
}
}
}

watch.Stop();

var size = new FileInfo(downloadPath).Length;
Logger.LogInformation($"Downloaded {size / 1024.0 / 1024.0:N1} MB in {(int)watch.Elapsed.TotalSeconds}s");
Logger.LogInformation($"Downloaded {size / 1024.0 / 1024.0:N1} MB in {watch.Elapsed:hh\\:mm\\:ss}");
}

var mount_point = Path.Combine(TempDirectory, filename + "-mount");
Expand Down

0 comments on commit c6d444e

Please sign in to comment.