Skip to content

Commit

Permalink
Merge #3859 Linux network fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Jul 21, 2023
2 parents 05a67aa + c3acd55 commit d1dd847
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 29 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ All notable changes to this project will be documented in this file.
- [GUI] Show download errors for upgrades (#3840 by: HebaruSan; reviewed: techman83)
- [Core] Stop trying to check free space on Mono (#3850 by: HebaruSan; reviewed: techman83)
- [Core] Handle missing KSP2 exe (#3854 by: HebaruSan; reviewed: techman83)
- [Core] Linux network fixes (#3859 by: HebaruSan; reviewed: techman83)

### Internal

Expand Down
1 change: 1 addition & 0 deletions Core/Extensions/CryptoExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public static byte[] ComputeHash(this HashAlgorithm hashAlgo, Stream stream,
{
// Done!
hashAlgo.TransformFinalBlock(buffer, 0, bytesRead);
progress.Report(100);
break;
}
else
Expand Down
6 changes: 5 additions & 1 deletion Core/Extensions/IOExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ public static DriveInfo GetDrive(this DirectoryInfo dir)
public static void CopyTo(this Stream src, Stream dest, IProgress<long> progress, CancellationToken cancelToken = default(CancellationToken))
{
// CopyTo says its default buffer is 81920, but we want more than 1 update for a 100 KiB file
const int bufSize = 8192;
const int bufSize = 16384;
var buffer = new byte[bufSize];
long total = 0;
// Make sure we get an initial progress notification at the start
progress.Report(total);
var lastProgressTime = DateTime.Now;
while (true)
{
Expand All @@ -91,6 +93,8 @@ public static DriveInfo GetDrive(this DirectoryInfo dir)
lastProgressTime = now;
}
}
// Make sure we get a final progress notification after we're done
progress.Report(total);
}

private static readonly TimeSpan progressInterval = TimeSpan.FromMilliseconds(200);
Expand Down
73 changes: 45 additions & 28 deletions Core/Net/NetAsyncDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,13 +312,11 @@ private void DownloadModule(Net.DownloadTarget target)
/// true to queue, false to start immediately
/// </returns>
private bool shouldQueue(Net.DownloadTarget target)
{
return downloads.Any(dl =>
=> downloads.Any(dl =>
(!dl.target.url.IsAbsoluteUri || dl.target.url.Host == target.url.Host)
&& dl.bytesLeft > 0
// Consider done if already tried and failed
&& dl.error == null);
}

private void triggerCompleted()
{
Expand Down Expand Up @@ -391,52 +389,71 @@ private void FileProgressReport(int index, int percent, long bytesDownloaded, lo
/// </summary>
private void FileDownloadComplete(int index, Exception error, bool canceled, string etag)
{
// Make sure the threads don't trip on one another
lock (dlMutex)
if (error != null)
{
if (error != null)
{
log.InfoFormat("Error downloading {0}: {1}", downloads[index].target.url, error.Message);
log.InfoFormat("Error downloading {0}: {1}", downloads[index].target.url, error.Message);

// Check whether we were already downloading the fallback url
if (!canceled && !downloads[index].triedFallback && downloads[index].target.fallbackUrl != null)
{
log.InfoFormat("Trying fallback URL: {0}", downloads[index].target.fallbackUrl);
// Encode spaces to avoid confusing URL parsers
User.RaiseMessage(Properties.Resources.NetAsyncDownloaderTryingFallback,
downloads[index].target.url.ToString().Replace(" ", "%20"),
downloads[index].target.fallbackUrl.ToString().Replace(" ", "%20")
);
// Try the fallbackUrl
downloads[index].triedFallback = true;
downloads[index].Download(downloads[index].target.fallbackUrl, downloads[index].path);
// Short circuit the completion process so the fallback can run
return;
}
else
{
downloads[index].error = error;
}
// Check whether we were already downloading the fallback url
if (!canceled && !downloads[index].triedFallback && downloads[index].target.fallbackUrl != null)
{
log.InfoFormat("Trying fallback URL: {0}", downloads[index].target.fallbackUrl);
// Encode spaces to avoid confusing URL parsers
User.RaiseMessage(Properties.Resources.NetAsyncDownloaderTryingFallback,
downloads[index].target.url.ToString().Replace(" ", "%20"),
downloads[index].target.fallbackUrl.ToString().Replace(" ", "%20")
);
// Try the fallbackUrl
downloads[index].triedFallback = true;
downloads[index].Download(downloads[index].target.fallbackUrl, downloads[index].path);
// Short circuit the completion process so the fallback can run
return;
}
else
{
log.InfoFormat("Finished downloading {0}", downloads[index].target.url);
downloads[index].error = error;
}
}
else
{
log.InfoFormat("Finished downloading {0}", downloads[index].target.url);
downloads[index].bytesLeft = 0;
}

// Make sure the threads don't trip on one another
lock (dlMutex)
{
// Start next download, if any
if (!canceled)
{
var next = queuedDownloads.FirstOrDefault(dl =>
!dl.url.IsAbsoluteUri || dl.url.Host == downloads[index].target.url.Host);
if (next != null)
{
log.DebugFormat("Attempting to start queued download {0}", next.url);
// Start this host's next queued download
queuedDownloads.Remove(next);
DownloadModule(next);
}
}
}

try
{
// Tell calling code that this file is ready
onOneCompleted?.Invoke(downloads[index].target.url, downloads[index].path, downloads[index].error, etag);
}
catch (Exception exc)
{
if (downloads[index].error == null)
{
// Capture anything that goes wrong with the post-download process as well
downloads[index].error = exc;
}
}

// Make sure the threads don't trip on one another
lock (dlMutex)
{
if (++completed_downloads >= downloads.Count + queuedDownloads.Count)
{
log.DebugFormat("Triggering completion at {0} completed, {1} started, {2} queued", completed_downloads, downloads.Count, queuedDownloads.Count);
Expand Down
3 changes: 3 additions & 0 deletions Core/Net/NetAsyncModulesDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ private void ModuleDownloadComplete(Uri url, string filename, Exception error, s
}
// If there was an error in STORING, delete the file so we can try it from scratch later
File.Delete(filename);

// Tell downloader there is a problem with this file
throw;
}
catch (OperationCanceledException exc)
{
Expand Down
1 change: 1 addition & 0 deletions Core/Net/ResumingWebClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ protected override void OnOpenReadCompleted(OpenReadCompletedEventArgs e)
bytesDownloaded, contentLength);
}),
cancelTokenSrc.Token);
// Make sure caller knows we've finished
DownloadProgress?.Invoke(100, contentLength, contentLength);
cancelTokenSrc = null;
}
Expand Down

0 comments on commit d1dd847

Please sign in to comment.