mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Make the Steam downloader parallel, add retries and multiple server support
This commit is contained in:
parent
25cd582797
commit
2e01293f58
@ -11,7 +11,7 @@ public static class CircuitBreaker
|
|||||||
public static int DEFAULT_DELAY_MULTIPLIER = 2;
|
public static int DEFAULT_DELAY_MULTIPLIER = 2;
|
||||||
public static int DEFAULT_RETRIES = 5;
|
public static int DEFAULT_RETRIES = 5;
|
||||||
|
|
||||||
public static async ValueTask<TR> WithAutoRetryAsync<TR, TE>(ILogger logger, Func<ValueTask<TR>> f,
|
public static async ValueTask<TR> WithAutoRetryAsync<TR, TE>(ILogger logger, Func<Task<TR>> f,
|
||||||
TimeSpan? delay = null, int? multipler = null, int? maxRetries = null) where TE : Exception
|
TimeSpan? delay = null, int? multipler = null, int? maxRetries = null) where TE : Exception
|
||||||
{
|
{
|
||||||
var retries = 0;
|
var retries = 0;
|
||||||
@ -37,7 +37,7 @@ public static class CircuitBreaker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async ValueTask WithAutoRetryAsync<TE>(ILogger logger, Func<ValueTask> f, TimeSpan? delay = null,
|
public static async ValueTask WithAutoRetryAsync<TE>(ILogger logger, Func<Task> f, TimeSpan? delay = null,
|
||||||
int? multipler = null, int? maxRetries = null) where TE : Exception
|
int? multipler = null, int? maxRetries = null) where TE : Exception
|
||||||
{
|
{
|
||||||
var retries = 0;
|
var retries = 0;
|
||||||
|
@ -419,7 +419,8 @@ public class Client : IDisposable
|
|||||||
return _cdnServers[_random.Next(0, _cdnServers.Length)];
|
return _cdnServers[_random.Next(0, _cdnServers.Length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Download(uint appId, uint depotId, ulong manifest, DepotManifest.FileData fileData, AbsolutePath output, CancellationToken token)
|
public async Task Download(uint appId, uint depotId, ulong manifest, DepotManifest.FileData fileData, AbsolutePath output,
|
||||||
|
CancellationToken token, IJob? parentJob = null)
|
||||||
{
|
{
|
||||||
await LoadCDNServers();
|
await LoadCDNServers();
|
||||||
|
|
||||||
@ -429,9 +430,12 @@ public class Client : IDisposable
|
|||||||
|
|
||||||
await fileData.Chunks.OrderBy(c => c.Offset)
|
await fileData.Chunks.OrderBy(c => c.Offset)
|
||||||
.PMapAll(async chunk =>
|
.PMapAll(async chunk =>
|
||||||
|
{
|
||||||
|
async Task<DepotChunk> AttemptDownload(DepotManifest.ChunkData chunk)
|
||||||
{
|
{
|
||||||
var client = RandomServer();
|
var client = RandomServer();
|
||||||
using var job = await _limiter.Begin($"Downloading chunk of {fileData.FileName}", chunk.CompressedLength, token);
|
using var job = await _limiter.Begin($"Downloading chunk of {fileData.FileName}",
|
||||||
|
chunk.CompressedLength, token);
|
||||||
|
|
||||||
var chunkId = chunk.ChunkID!.ToHex();
|
var chunkId = chunk.ChunkID!.ToHex();
|
||||||
|
|
||||||
@ -446,13 +450,21 @@ public class Client : IDisposable
|
|||||||
|
|
||||||
var data = await _httpClient.GetByteArrayAsync(uri, token);
|
var data = await _httpClient.GetByteArrayAsync(uri, token);
|
||||||
await job.Report(data.Length, token);
|
await job.Report(data.Length, token);
|
||||||
|
|
||||||
|
if (parentJob != null)
|
||||||
|
await parentJob.Report(data.Length, token);
|
||||||
|
|
||||||
var chunkData = new DepotChunk(chunk, data);
|
var chunkData = new DepotChunk(chunk, data);
|
||||||
chunkData.Process(depotKey);
|
chunkData.Process(depotKey);
|
||||||
|
|
||||||
return chunkData;
|
return chunkData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await CircuitBreaker.WithAutoRetryAsync<DepotChunk, HttpRequestException>(_logger, () => AttemptDownload(chunk));
|
||||||
}).Do(async data =>
|
}).Do(async data =>
|
||||||
{
|
{
|
||||||
await os.WriteAsync(data.Data, token);
|
await os.WriteAsync(data.Data, token);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user