Remove several uses of .Wait

This commit is contained in:
Timothy Baldridge 2020-06-01 14:26:03 -06:00
parent 0933e15c9e
commit 0960600f05
7 changed files with 57 additions and 21 deletions

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Wabbajack.Common namespace Wabbajack.Common
@ -9,7 +10,7 @@ namespace Wabbajack.Common
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> WithAutoRetry<TR, TE>(Func<ValueTask<TR>> f, TimeSpan? delay = null, int? multipler = null, int? maxRetries = null) where TE : Exception public static async ValueTask<TR> WithAutoRetryAsync<TR, TE>(Func<ValueTask<TR>> f, TimeSpan? delay = null, int? multipler = null, int? maxRetries = null) where TE : Exception
{ {
int retries = 0; int retries = 0;
delay ??= DEFAULT_DELAY; delay ??= DEFAULT_DELAY;
@ -33,7 +34,7 @@ namespace Wabbajack.Common
} }
} }
public static async ValueTask WithAutoRetry<TE>(Func<ValueTask> f, TimeSpan? delay = null, int? multipler = null, int? maxRetries = null) where TE : Exception public static async ValueTask WithAutoRetryAsync<TE>(Func<ValueTask> f, TimeSpan? delay = null, int? multipler = null, int? maxRetries = null) where TE : Exception
{ {
int retries = 0; int retries = 0;
delay ??= DEFAULT_DELAY; delay ??= DEFAULT_DELAY;
@ -56,6 +57,30 @@ namespace Wabbajack.Common
goto TOP; goto TOP;
} }
} }
public static void WithAutoRetry<TE>(Action f, TimeSpan? delay = null, int? multipler = null, int? maxRetries = null) where TE : Exception
{
int retries = 0;
delay ??= DEFAULT_DELAY;
multipler ??= DEFAULT_DELAY_MULTIPLIER;
maxRetries ??= DEFAULT_RETRIES;
TOP:
try
{
f();
}
catch (TE ex)
{
retries += 1;
if (retries > maxRetries)
throw;
Utils.Log($"(Retry {retries} of {maxRetries}), got exception {ex.Message}, waiting {delay.Value.TotalMilliseconds}ms");
Thread.Sleep(delay.Value);
delay = delay * multipler;
goto TOP;
}
}
} }
} }

View File

@ -12,13 +12,16 @@ namespace Wabbajack.Common
public const string Downloading = "downloading"; public const string Downloading = "downloading";
public const string BeginInstall = "begin_install"; public const string BeginInstall = "begin_install";
public const string FinishInstall = "finish_install"; public const string FinishInstall = "finish_install";
private static AsyncLock _creationLock = new AsyncLock();
static Metrics() public static async ValueTask<string> GetMetricsKey()
{ {
using var _ = await _creationLock.WaitAsync();
if (!Utils.HaveEncryptedJson(Consts.MetricsKeyHeader)) if (!Utils.HaveEncryptedJson(Consts.MetricsKeyHeader))
{ {
Utils.MakeRandomKey().ToEcryptedJson(Consts.MetricsKeyHeader).AsTask().Wait(); await Utils.MakeRandomKey().ToEcryptedJson(Consts.MetricsKeyHeader);
} }
return await Utils.FromEncryptedJson<string>(Consts.MetricsKeyHeader);
} }
/// <summary> /// <summary>
/// This is all we track for metrics, action, and value. The action will be like /// This is all we track for metrics, action, and value. The action will be like
@ -31,8 +34,7 @@ namespace Wabbajack.Common
var client = new HttpClient(); var client = new HttpClient();
try try
{ {
client.DefaultRequestHeaders.Add(Consts.MetricsKeyHeader, client.DefaultRequestHeaders.Add(Consts.MetricsKeyHeader, await GetMetricsKey());
await Utils.FromEncryptedJson<string>(Consts.MetricsKeyHeader));
await client.GetAsync($"{Consts.WabbajackBuildServerUri}metrics/{action}/{value}"); await client.GetAsync($"{Consts.WabbajackBuildServerUri}metrics/{action}/{value}");
} }
catch (Exception) catch (Exception)

View File

@ -95,13 +95,13 @@ namespace Wabbajack.Common
public ValueTask<FileStream> Create() public ValueTask<FileStream> Create()
{ {
var path = _path; var path = _path;
return CircuitBreaker.WithAutoRetry<FileStream, IOException>(async () => File.Open(path, FileMode.Create, FileAccess.ReadWrite)); return CircuitBreaker.WithAutoRetryAsync<FileStream, IOException>(async () => File.Open(path, FileMode.Create, FileAccess.ReadWrite));
} }
public ValueTask<FileStream> OpenWrite() public ValueTask<FileStream> OpenWrite()
{ {
var path = _path; var path = _path;
return CircuitBreaker.WithAutoRetry<FileStream, IOException>(async () => File.OpenWrite(path)); return CircuitBreaker.WithAutoRetryAsync<FileStream, IOException>(async () => File.OpenWrite(path));
} }
public async Task WriteAllTextAsync(string text) public async Task WriteAllTextAsync(string text)
@ -255,7 +255,17 @@ namespace Wabbajack.Common
if (IsReadOnly) IsReadOnly = false; if (IsReadOnly) IsReadOnly = false;
var path = _path; var path = _path;
await CircuitBreaker.WithAutoRetry<IOException>(async () => File.Delete(path)); await CircuitBreaker.WithAutoRetryAsync<IOException>(async () => File.Delete(path));
}
public void Delete()
{
if (!IsFile) return;
if (IsReadOnly) IsReadOnly = false;
var path = _path;
CircuitBreaker.WithAutoRetry<IOException>(async () => File.Delete(path));
} }
public bool InFolder(AbsolutePath folder) public bool InFolder(AbsolutePath folder)
@ -381,14 +391,14 @@ namespace Wabbajack.Common
public ValueTask<FileStream> OpenShared() public ValueTask<FileStream> OpenShared()
{ {
var path = _path; var path = _path;
return CircuitBreaker.WithAutoRetry<FileStream, IOException>(async () => return CircuitBreaker.WithAutoRetryAsync<FileStream, IOException>(async () =>
File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
} }
public ValueTask<FileStream> WriteShared() public ValueTask<FileStream> WriteShared()
{ {
var path = _path; var path = _path;
return CircuitBreaker.WithAutoRetry<FileStream, IOException>(async () => return CircuitBreaker.WithAutoRetryAsync<FileStream, IOException>(async () =>
File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite)); File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite));
} }

View File

@ -89,7 +89,7 @@ namespace Wabbajack.Common
{ {
try try
{ {
f.DeleteAsync().Wait(); f.Delete();
success++; success++;
} }
catch (Exception e) catch (Exception e)

View File

@ -1,12 +1,13 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Wabbajack.Common; using Wabbajack.Common;
using Wabbajack.Common.StatusFeed;
namespace Wabbajack.Lib namespace Wabbajack.Lib
{ {
/// <summary> /// <summary>
/// This should probably be replaced with an error, but this is just to get messageboxes out of the .Lib library /// This should probably be replaced with an error, but this is just to get messageboxes out of the .Lib library
/// </summary> /// </summary>
public class CriticalFailureIntervention : AUserIntervention public class CriticalFailureIntervention : AErrorMessage
{ {
private TaskCompletionSource<ConfirmationIntervention.Choice> _source = new TaskCompletionSource<ConfirmationIntervention.Choice>(); private TaskCompletionSource<ConfirmationIntervention.Choice> _source = new TaskCompletionSource<ConfirmationIntervention.Choice>();
public Task<ConfirmationIntervention.Choice> Task => _source.Task; public Task<ConfirmationIntervention.Choice> Task => _source.Task;
@ -18,9 +19,8 @@ namespace Wabbajack.Lib
} }
public override string ShortDescription { get; } public override string ShortDescription { get; }
public override string ExtendedDescription { get; } public override string ExtendedDescription { get; }
public override void Cancel() public void Cancel()
{ {
Handled = true;
_source.SetResult(ConfirmationIntervention.Choice.Abort); _source.SetResult(ConfirmationIntervention.Choice.Abort);
} }
} }

View File

@ -8,7 +8,7 @@ using Xunit.Abstractions;
namespace Wabbajack.Test namespace Wabbajack.Test
{ {
public abstract class ACompilerTest : XunitContextBase, IDisposable public abstract class ACompilerTest : XunitContextBase, IAsyncDisposable
{ {
private IDisposable _unsub; private IDisposable _unsub;
protected TestUtils utils { get; set; } protected TestUtils utils { get; set; }
@ -26,9 +26,9 @@ namespace Wabbajack.Test
} }
public override void Dispose() public async ValueTask DisposeAsync()
{ {
utils.DisposeAsync().AsTask().Wait(); await utils.DisposeAsync();
_unsub.Dispose(); _unsub.Dispose();
base.Dispose(); base.Dispose();
} }

View File

@ -102,11 +102,10 @@ namespace Wabbajack
{ {
if (Path.GetDirectoryName(Assembly.GetEntryAssembly().Location.ToLower()) == KnownFolders.Downloads.Path.ToLower()) if (Path.GetDirectoryName(Assembly.GetEntryAssembly().Location.ToLower()) == KnownFolders.Downloads.Path.ToLower())
{ {
Utils.Log(new CriticalFailureIntervention( Utils.Error(new CriticalFailureIntervention(
"Wabbajack is running inside your Downloads folder. This folder is often highly monitored by antivirus software and these can often " + "Wabbajack is running inside your Downloads folder. This folder is often highly monitored by antivirus software and these can often " +
"conflict with the operations Wabbajack needs to perform. Please move this executable outside of your Downloads folder and then restart the app.", "conflict with the operations Wabbajack needs to perform. Please move this executable outside of your Downloads folder and then restart the app.",
"Cannot run inside Downloads")).Task.Wait(); "Cannot run inside Downloads"));
Environment.Exit(1);
} }
MWVM = mainWindowVM; MWVM = mainWindowVM;