Use synchronous zipfile extraction

Asynchronous methods have issues: https://stackoverflow.com/questions/44124324/parallel-foreach-throws-exception-when-extracting-a-zip-file
This commit is contained in:
Cyberboss
2018-08-27 12:16:06 -04:00
parent 6c8a96e5ea
commit 8a548c6c0c
2 changed files with 6 additions and 41 deletions
@@ -113,28 +113,8 @@ namespace Tgstation.Server.Host.Components.Byond
try
{
//byond can just decide to corrupt the zip fnr
//(or maybe our downloader is a shite)
//either way try a few times
for (var I = 0; I < 3; ++I)
{
var download = await downloadTask.ConfigureAwait(false);
try
{
await ioManager.ZipToDirectory(versionKey, download, cancellationToken).ConfigureAwait(false);
break;
}
catch (OperationCanceledException)
{
throw;
}
catch
{
if (I == 2)
throw;
downloadTask = byondInstaller.DownloadVersion(version, cancellationToken);
}
}
var download = await downloadTask.ConfigureAwait(false);
await ioManager.ZipToDirectory(versionKey, download, cancellationToken).ConfigureAwait(false);
await byondInstaller.InstallByond(ioManager.ResolvePath(versionKey), version, cancellationToken).ConfigureAwait(false);
//make sure to do this last because this is what tells us we have a valid version in the future
@@ -300,30 +300,15 @@ namespace Tgstation.Server.Host.IO
}
/// <inheritdoc />
public async Task ZipToDirectory(string path, byte[] zipFileBytes, CancellationToken cancellationToken)
public Task ZipToDirectory(string path, byte[] zipFileBytes, CancellationToken cancellationToken) => Task.Factory.StartNew(() =>
{
path = ResolvePath(path);
if (zipFileBytes == null)
throw new ArgumentNullException(nameof(zipFileBytes));
using (var ms = new MemoryStream(zipFileBytes))
{
zipFileBytes = null;
using (var archive = new ZipArchive(ms))
{
string GetEntryName(ZipArchiveEntry entry) => ConcatPath(path, entry.FullName);
//create directories first
await Task.WhenAll(CreateDirectory(path, cancellationToken), Task.WhenAll(archive.Entries.Where(x => x.Name.Length == 0).Select(x => CreateDirectory(GetEntryName(x), cancellationToken)))).ConfigureAwait(false);
//extract files
await Task.WhenAll(archive.Entries.Where(x => x.Name.Length > 0).Select(async x =>
{
var entryPath = GetEntryName(x);
using (var stream = x.Open())
using (var file = OpenWriteStream(entryPath))
await stream.CopyToAsync(file).ConfigureAwait(false);
})).ConfigureAwait(false);
}
}
}
using (var archive = new ZipArchive(ms, ZipArchiveMode.Read))
archive.ExtractToDirectory(path);
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
}
}