mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-31 09:02:41 +01:00
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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user