Fixed a deadlock in the sanity tests

This commit is contained in:
Timothy Baldridge 2020-03-28 21:29:27 -06:00
parent ea3f33350c
commit 06b3479230
10 changed files with 84 additions and 17 deletions

View File

@ -0,0 +1,46 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Wabbajack.Common
{
public class AsyncBlockingCollection<T> : IDisposable
{
private readonly ConcurrentQueue<T> _collection;
private bool isDisposed = false;
public AsyncBlockingCollection()
{
_collection = new ConcurrentQueue<T>();
}
public void Add(T val)
{
_collection.Enqueue(val);
}
public async ValueTask<(bool found, T val)> TryTake(TimeSpan timeout, CancellationToken token)
{
var startTime = DateTime.Now;
while (true)
{
if (_collection.TryDequeue(out T result))
{
return (true, result);
}
if (DateTime.Now - startTime > timeout || token.IsCancellationRequested || isDisposed)
return (false, default);
await Task.Delay(100);
}
}
public void Dispose()
{
isDisposed = true;
}
}
}

View File

@ -17,7 +17,7 @@ namespace Wabbajack.Common
public static RelativePath LOOTFolderFilesDir = (RelativePath)"LOOT Config Files";
public static RelativePath BSACreationDir = (RelativePath)"TEMP_BSA_FILES";
public static AbsolutePath ModListDownloadFolder = "downloaded_mod_lists".RelativeTo(AbsolutePath.EntryPoint);
public static AbsolutePath ModListDownloadFolder => "downloaded_mod_lists".RelativeTo(AbsolutePath.EntryPoint);
public static string MegaPrefix = "https://mega.nz/#!";
@ -114,9 +114,9 @@ namespace Wabbajack.Common
public static AbsolutePath PatchCacheFolder => LocalAppDataPath.Combine("patch_cache");
public static int MaxConnectionsPerServer = 4;
public static AbsolutePath LogsFolder = ((RelativePath)"logs").RelativeToEntryPoint();
public static AbsolutePath EntryPoint = (AbsolutePath)(Assembly.GetEntryAssembly()?.Location ?? (string)((RelativePath)"Unknown").RelativeToWorkingDirectory());
public static AbsolutePath LogFile = LogsFolder.Combine(EntryPoint.FileNameWithoutExtension + ".current.log");
public static AbsolutePath LogsFolder => ((RelativePath)"logs").RelativeToEntryPoint();
public static AbsolutePath EntryPoint => (AbsolutePath)(Assembly.GetEntryAssembly()?.Location ?? (string)((RelativePath)"Unknown").RelativeToWorkingDirectory());
public static AbsolutePath LogFile => LogsFolder.Combine(EntryPoint.FileNameWithoutExtension + ".current.log");
public static int MaxOldLogs = 50;
public static Extension BSA = new Extension(".BSA");
public static Extension MOHIDDEN = new Extension(".mohidden");

View File

@ -167,7 +167,17 @@ namespace Wabbajack.Common
}
}
public static AbsolutePath EntryPoint => ((AbsolutePath)Assembly.GetEntryAssembly().Location).Parent;
public static AbsolutePath EntryPoint
{
get
{
var location = Assembly.GetEntryAssembly()?.Location ?? null;
if (location == null)
location = Assembly.GetExecutingAssembly().Location ?? null;
return ((AbsolutePath)location).Parent;
}
}
/// <summary>
/// Moves this file to the specified location
@ -382,17 +392,22 @@ namespace Wabbajack.Common
public RelativePath(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
_path = null;
Extension = default;
return;
}
var trimmed = path.ToLowerInvariant().Replace("/", "\\").Trim('\\');
if (string.IsNullOrEmpty(trimmed))
{
_path = null;
Extension = default;
return;
}
else
{
_path = trimmed;
Extension = new Extension(Path.GetExtension(path));
}
_path = trimmed;
Extension = new Extension(Path.GetExtension(path));
Validate();
}
@ -428,7 +443,7 @@ namespace Wabbajack.Common
public AbsolutePath RelativeToEntryPoint()
{
return RelativeTo(((AbsolutePath)Assembly.GetEntryAssembly().Location).Parent);
return RelativeTo(AbsolutePath.EntryPoint);
}
public AbsolutePath RelativeToWorkingDirectory()

View File

@ -515,7 +515,7 @@ namespace Wabbajack.Common
{
while (remainingTasks > 0)
{
var (got, a) = await queue.Queue.TryTake(TimeSpan.FromMilliseconds(200), CancellationToken.None);
var (got, a) = await queue.Queue.TryTake(TimeSpan.FromMilliseconds(100), CancellationToken.None);
if (got)
{
await a();

View File

@ -16,7 +16,7 @@ namespace Wabbajack.Common
{
public class WorkQueue : IDisposable
{
internal BlockingCollection<Func<Task>> Queue = new BlockingCollection<Func<Task>>(new ConcurrentStack<Func<Task>>());
internal AsyncBlockingCollection<Func<Task>> Queue = new AsyncBlockingCollection<Func<Task>>();
public const int UnassignedCpuId = 0;
@ -51,7 +51,7 @@ namespace Wabbajack.Common
private readonly Subject<IObservable<int>> _activeNumThreadsObservable = new Subject<IObservable<int>>();
public const int PollMS = 200;
public static TimeSpan PollMS = TimeSpan.FromMilliseconds(200);
/// <summary>
/// Creates a WorkQueue with the given number of threads
@ -125,7 +125,7 @@ namespace Wabbajack.Common
bool got;
try
{
got = Queue.TryTake(out f, PollMS, _shutdown.Token);
(got, f) = await Queue.TryTake(PollMS, _shutdown.Token);
}
catch (Exception)
{

View File

@ -164,10 +164,12 @@ namespace Wabbajack.Lib
throw new InvalidDataException("Can't start the processor twice");
}
Utils.Log("Starting Installer Task");
return Task.Run(async () =>
{
try
{
Utils.Log("Installation has Started");
_isRunning.OnNext(true);
return await _Begin(_cancel.Token);
}

View File

@ -53,7 +53,7 @@ namespace Wabbajack.Lib.CompilationSteps
}
}
var installationFile = modIni?.General?.installationFile;
var installationFile = (RelativePath)modIni?.General?.installationFile;
VirtualFile found = null;

View File

@ -46,6 +46,7 @@ namespace Wabbajack.Lib
{
if (cancel.IsCancellationRequested) return false;
var metric = Metrics.Send(Metrics.BeginInstall, ModList.Name);
Utils.Log("Configuring Processor");
ConfigureProcessor(20, ConstructDynamicNumThreads(await RecommendQueueSize()));
var game = ModList.GameType.MetaData();

View File

@ -42,7 +42,7 @@ namespace Wabbajack.Lib
public IncludeZEditPatches(ACompiler compiler) : base(compiler)
{
var zEditPath = FindzEditPath(compiler);
var havezEdit = zEditPath != null;
var havezEdit = zEditPath != default;
Utils.Log(havezEdit ? $"Found zEdit at {zEditPath}" : $"zEdit not detected, disabling zEdit routines");

View File

@ -57,7 +57,9 @@ namespace Wabbajack.Test
protected async Task Install(MO2Compiler compiler)
{
Utils.Log("Loading Modlist");
var modlist = AInstaller.LoadFromFile(compiler.ModListOutputFile);
Utils.Log("Constructing Installer");
var installer = new MO2Installer(
archive: compiler.ModListOutputFile,
modList: modlist,
@ -66,6 +68,7 @@ namespace Wabbajack.Test
parameters: CreateDummySystemParameters());
installer.WarnOnOverwrite = false;
installer.GameFolder = utils.GameFolder;
Utils.Log("Starting Install");
await installer.Begin();
}