From 0a11fedc8db0c118c1ae406f368d77930b2191f0 Mon Sep 17 00:00:00 2001 From: ryannewington Date: Tue, 23 Jan 2018 16:06:49 +1100 Subject: [PATCH] Fixes issue #116 --- .../MAInterface/MAController.cs | 99 +++++++++++-------- 1 file changed, 59 insertions(+), 40 deletions(-) diff --git a/src/Lithnet.Miiserver.AutoSync/MAInterface/MAController.cs b/src/Lithnet.Miiserver.AutoSync/MAInterface/MAController.cs index 1f6c2c4..b5a85d8 100644 --- a/src/Lithnet.Miiserver.AutoSync/MAInterface/MAController.cs +++ b/src/Lithnet.Miiserver.AutoSync/MAInterface/MAController.cs @@ -33,15 +33,19 @@ internal class MAController protected static ConcurrentDictionary AllMaLocalOperationLocks; public delegate void SyncCompleteEventHandler(object sender, SyncCompleteEventArgs e); + public static event SyncCompleteEventHandler SyncComplete; public delegate void RunProfileExecutionCompleteEventHandler(object sender, RunProfileExecutionCompleteEventArgs e); + public event RunProfileExecutionCompleteEventHandler RunProfileExecutionComplete; public delegate void StateChangedEventHandler(object sender, MAStatusChangedEventArgs e); + public event StateChangedEventHandler StateChanged; public delegate void MessageLoggedEventHandler(object sender, MessageLoggedEventArgs e); + public event MessageLoggedEventHandler MessageLogged; private SemaphoreSlim localOperationLock; @@ -684,7 +688,7 @@ private void Debug(string message) #endif } - private void Wait(TimeSpan duration, string name, CancellationTokenSource ts, [CallerMemberName]string caller = "") + private void Wait(TimeSpan duration, string name, CancellationTokenSource ts, [CallerMemberName] string caller = "") { ts.Token.ThrowIfCancellationRequested(); this.Debug($"SLEEP: {name}: {duration}: {caller}"); @@ -692,7 +696,7 @@ private void Wait(TimeSpan duration, string name, CancellationTokenSource ts, [C ts.Token.ThrowIfCancellationRequested(); } - private void Wait(WaitHandle wh, string name, CancellationTokenSource ts, [CallerMemberName]string caller = "") + private void Wait(WaitHandle wh, string name, CancellationTokenSource ts, [CallerMemberName] string caller = "") { this.Debug($"LOCK: WAIT: {name}: {caller}"); WaitHandle.WaitAny(new[] { wh, ts.Token.WaitHandle }); @@ -700,7 +704,7 @@ private void Wait(WaitHandle wh, string name, CancellationTokenSource ts, [Calle this.Debug($"LOCK: CLEARED: {name}: {caller}"); } - private void WaitAndTakeLock(SemaphoreSlim mre, string name, CancellationTokenSource ts, [CallerMemberName]string caller = "") + private void WaitAndTakeLock(SemaphoreSlim mre, string name, CancellationTokenSource ts, [CallerMemberName] string caller = "") { this.Debug($"LOCK: WAIT: {name}: {caller}"); mre.Wait(ts.Token); @@ -708,7 +712,7 @@ private void WaitAndTakeLock(SemaphoreSlim mre, string name, CancellationTokenSo this.Debug($"LOCK: TAKE: {name}: {caller}"); } - private void WaitAndTakeLockWithSemaphore(EventWaitHandle mre, SemaphoreSlim sem, string name, CancellationTokenSource ts, [CallerMemberName]string caller = "") + private void WaitAndTakeLockWithSemaphore(EventWaitHandle mre, SemaphoreSlim sem, string name, CancellationTokenSource ts, [CallerMemberName] string caller = "") { bool gotLock = false; @@ -733,7 +737,7 @@ private void WaitAndTakeLockWithSemaphore(EventWaitHandle mre, SemaphoreSlim sem } } - private void Wait(WaitHandle[] waitHandles, string name, CancellationTokenSource ts, [CallerMemberName]string caller = "") + private void Wait(WaitHandle[] waitHandles, string name, CancellationTokenSource ts, [CallerMemberName] string caller = "") { this.Debug($"LOCK: WAIT: {name}: {caller}"); while (!WaitHandle.WaitAll(waitHandles, 1000)) @@ -752,7 +756,7 @@ private void TakeLockUnsafe(EventWaitHandle mre, string name, CancellationTokenS ts.Token.ThrowIfCancellationRequested(); } - private void ReleaseLock(EventWaitHandle mre, string name, [CallerMemberName]string caller = "") + private void ReleaseLock(EventWaitHandle mre, string name, [CallerMemberName] string caller = "") { this.Debug($"LOCK: RELEASE: {name}: {caller}"); mre.Set(); @@ -1912,50 +1916,28 @@ private void CheckAndQueueUnmanagedChanges() this.WaitAndTakeLock(this.localOperationLock, nameof(this.localOperationLock), this.controllerCancellationTokenSource); hasLocalLock = true; - this.Trace("Checking for unmanaged changes"); - RunDetails run = this.ma.GetLastRun(); + bool hasRun = this.lastRunNumber > 0; + int lastKnownRun = this.lastRunNumber; - if (run == null || this.lastRunNumber == run.RunNumber) - { - return; - } - - this.Trace($"Unprocessed changes detected. Last recorded run: {this.lastRunNumber}. Last run in sync engine: {run.RunNumber}"); + RunDetails run = this.ma.GetLastRun(); + this.lastRunNumber = run?.RunNumber ?? 0; - this.lastRunNumber = run.RunNumber; + this.Trace("Checking for unmanaged changes"); - foreach (PartitionConfiguration c in this.GetPartitionsRequiringExport()) + if (hasRun && run != null) { - if (c.ExportRunProfileName != null) + if (lastKnownRun == this.lastRunNumber) { - ExecutionParameters p = new ExecutionParameters(c.ExportRunProfileName); - this.AddPendingActionIfNotQueued(p, "Pending export check"); + return; } - } - if (run?.StepDetails != null) - { - foreach (StepDetails step in run.StepDetails) - { - if (step.HasUnconfirmedExports()) - { - PartitionConfiguration c = this.Configuration.Partitions.GetActiveItemOrNull(step.StepDefinition.Partition); + this.Trace($"Unprocessed changes detected. Last recorded run: {lastKnownRun}. Last run in sync engine: {run.RunNumber}"); - if (c != null) - { - this.AddPendingActionIfNotQueued(new ExecutionParameters(c.ConfirmingImportRunProfileName), "Unconfirmed export check"); - } - } - } + this.PerformPostRunActions(run); } - - foreach (PartitionConfiguration c in this.GetPartitionsRequiringSync()) + else { - if (c.ExportRunProfileName != null) - { - ExecutionParameters p = new ExecutionParameters(c.DeltaSyncRunProfileName); - this.AddPendingActionIfNotQueued(p, "Staged import check"); - } + this.CheckAndQueueUnmanagedChanges(run); } } finally @@ -1968,6 +1950,43 @@ private void CheckAndQueueUnmanagedChanges() } } + private void CheckAndQueueUnmanagedChanges(RunDetails run) + { + foreach (PartitionConfiguration c in this.GetPartitionsRequiringExport()) + { + if (c.ExportRunProfileName != null) + { + ExecutionParameters p = new ExecutionParameters(c.ExportRunProfileName); + this.AddPendingActionIfNotQueued(p, "Pending export check"); + } + } + + if (run?.StepDetails != null) + { + foreach (StepDetails step in run.StepDetails) + { + if (step.HasUnconfirmedExports()) + { + PartitionConfiguration c = this.Configuration.Partitions.GetActiveItemOrNull(step.StepDefinition.Partition); + + if (c != null) + { + this.AddPendingActionIfNotQueued(new ExecutionParameters(c.ConfirmingImportRunProfileName), "Unconfirmed export check"); + } + } + } + } + + foreach (PartitionConfiguration c in this.GetPartitionsRequiringSync()) + { + if (c.ExportRunProfileName != null) + { + ExecutionParameters p = new ExecutionParameters(c.DeltaSyncRunProfileName); + this.AddPendingActionIfNotQueued(p, "Staged import check"); + } + } + } + private void MAController_SyncComplete(object sender, SyncCompleteEventArgs e) { if (e.TargetMA != this.ma.ID)