public void StateMachineCallbackTest1() { var callback = new TestCallback(); fht1.UnsafeRegisterCallback(callback); Prepare(out var f, out var s1, out var s2); // We should be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); callback.CheckInvoked(fht1.SystemState); // Refresh session s2 s2.Refresh(); s1.Refresh(); // We should now be in IN_PROGRESS, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.IN_PROGRESS, 2), fht1.SystemState)); callback.CheckInvoked(fht1.SystemState); s2.Refresh(); // We should be in WAIT_PENDING, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.WAIT_PENDING, 2), fht1.SystemState)); callback.CheckInvoked(fht1.SystemState); s1.Refresh(); // We should be in WAIT_FLUSH, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.WAIT_FLUSH, 2), fht1.SystemState)); callback.CheckInvoked(fht1.SystemState); s2.Refresh(); // We should be in PERSISTENCE_CALLBACK, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PERSISTENCE_CALLBACK, 2), fht1.SystemState)); callback.CheckInvoked(fht1.SystemState); // Expect checkpoint completion callback f.checkpointCallbackExpectation = 1; s1.Refresh(); // Completion callback should have been called once Assert.IsTrue(f.checkpointCallbackExpectation == 0); // We should be in REST, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 2), fht1.SystemState)); callback.CheckInvoked(fht1.SystemState); // Dispose session s2; does not move state machine forward s2.Dispose(); s1.Dispose(); RecoverAndTest(log); }
public void StateMachineTest1() { Prepare(out var f, out var s1, out var s2); // We should be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); // Refresh session s2 s2.Refresh(); // s1 has not refreshed, so we should still be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); // Refresh s1 s1.Refresh(); // We should now be in IN_PROGRESS, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.IN_PROGRESS, 2), fht1.SystemState)); s2.Refresh(); // We should be in WAIT_PENDING, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.WAIT_PENDING, 2), fht1.SystemState)); s1.Refresh(); // We should be in WAIT_FLUSH, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.WAIT_FLUSH, 2), fht1.SystemState)); s2.Refresh(); // We should be in PERSISTENCE_CALLBACK, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PERSISTENCE_CALLBACK, 2), fht1.SystemState)); // Expect checkpoint completion callback f.checkpointCallbackExpectation = 1; s1.Refresh(); // Completion callback should have been called once Assert.AreEqual(0, f.checkpointCallbackExpectation); // We should be in REST, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 2), fht1.SystemState)); // Dispose session s2; does not move state machine forward s2.Dispose(); s1.Dispose(); RecoverAndTest(log); }
public void StateMachineTest4() { Prepare(out var f, out var s1, out var uc1, out var s2); // We should be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); // Refresh session s2 s2.Refresh(); // s1 has not refreshed, so we should still be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); // Refresh s1 uc1.Refresh(); // We should now be in IN_PROGRESS, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.IN_PROGRESS, 2), fht1.SystemState)); // s1 is now in IN_PROGRESS, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.IN_PROGRESS, 2), SystemState.Make(s1.ctx.phase, s1.ctx.version))); // Suspend s1 uc1.SuspendThread(); // Since s2 is the only session now, it will fast-foward state machine // to completion s2.Refresh(); // We should be in REST, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 2), fht1.SystemState)); // Expect checkpoint completion callback f.checkpointCallbackExpectation = 1; uc1.ResumeThread(); // Completion callback should have been called once Assert.AreEqual(0, f.checkpointCallbackExpectation); s2.Dispose(); uc1.SuspendThread(); uc1.Dispose(); s1.Dispose(); RecoverAndTest(log); }
void Prepare(out SimpleFunctions f, out ClientSession <AdId, NumClicks, NumClicks, NumClicks, Empty, SimpleFunctions> s1, out UnsafeContext <AdId, NumClicks, NumClicks, NumClicks, Empty, SimpleFunctions> uc1, out ThreadSession <AdId, NumClicks, NumClicks, NumClicks, Empty, SimpleFunctions> s2, long toVersion = -1) { f = new SimpleFunctions(); // We should be in REST, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 1), fht1.SystemState)); // Take index checkpoint for recovery purposes fht1.TryInitiateIndexCheckpoint(out _); fht1.CompleteCheckpointAsync().AsTask().GetAwaiter().GetResult(); // Index checkpoint does not update version, so // we should still be in REST, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 1), fht1.SystemState)); NumClicks value; s1 = fht1.For(f).NewSession <SimpleFunctions>("foo"); for (int key = 0; key < numOps; key++) { value.numClicks = key; s1.Upsert(ref inputArray[key], ref value, Empty.Default, key); } // Ensure state machine needs no I/O wait during WAIT_FLUSH fht1.Log.ShiftReadOnlyAddress(fht1.Log.TailAddress, true); // Create unsafe context and hold epoch to prepare for manual state machine driver uc1 = s1.GetUnsafeContext(); uc1.ResumeThread(); // Start session s2 on another thread for testing s2 = fht1.For(f).CreateThreadSession(f); // We should be in REST, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 1), fht1.SystemState)); fht1.TryInitiateHybridLogCheckpoint(out _, CheckpointType.FoldOver, targetVersion: toVersion); // We should be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); }
public void VersionChangeTest() { var toVersion = 1 + (1 << 14); Prepare(out var f, out var s1, out var uc1, out var s2, toVersion); // We should be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); // Refresh session s2 s2.Refresh(); uc1.Refresh(); // We should now be in IN_PROGRESS, toVersion Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.IN_PROGRESS, toVersion), fht1.SystemState)); s2.Refresh(); // We should be in WAIT_FLUSH, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.WAIT_FLUSH, toVersion), fht1.SystemState)); // Expect checkpoint completion callback f.checkpointCallbackExpectation = 1; uc1.Refresh(); // Completion callback should have been called once Assert.IsTrue(f.checkpointCallbackExpectation == 0); // We should be in PERSISTENCE_CALLBACK, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PERSISTENCE_CALLBACK, toVersion), fht1.SystemState)); s2.Refresh(); Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, toVersion), fht1.SystemState)); // Dispose session s2; does not move state machine forward s2.Dispose(); uc1.SuspendThread(); uc1.Dispose(); s1.Dispose(); RecoverAndTest(log); }
public void VersionChangeRollOverTest() { var toVersion = 1 + (1 << 14); Prepare(out var f, out var s1, out var s2, toVersion); // We should be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); // Refresh session s2 s2.Refresh(); s1.Refresh(); // We should now be in IN_PROGRESS, toVersion + 1 (because of rollover of 13 bit short version) Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.IN_PROGRESS, toVersion + 1), fht1.SystemState)); s2.Refresh(); // We should be in WAIT_PENDING, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.WAIT_PENDING, toVersion + 1), fht1.SystemState)); s1.Refresh(); // We should be in WAIT_FLUSH, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.WAIT_FLUSH, toVersion + 1), fht1.SystemState)); s2.Refresh(); // We should be in PERSISTENCE_CALLBACK, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PERSISTENCE_CALLBACK, toVersion + 1), fht1.SystemState)); // Expect checkpoint completion callback f.checkpointCallbackExpectation = 1; s1.Refresh(); Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, toVersion + 1), fht1.SystemState)); // Dispose session s2; does not move state machine forward s2.Dispose(); s1.Dispose(); RecoverAndTest(log); }
public void StateMachineTest2() { Prepare(out var f, out var s1, out var s2); // We should be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); // Refresh session s2 s2.Refresh(); // s1 has not refreshed, so we should still be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); // Refresh s1 s1.Refresh(); // We should now be in IN_PROGRESS, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.IN_PROGRESS, 2), fht1.SystemState)); // Dispose session s2; does not move state machine forward s2.Dispose(); // We should still be in IN_PROGRESS, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.IN_PROGRESS, 2), fht1.SystemState)); // Expect checkpoint completion callback f.checkpointCallbackExpectation = 1; // Since s1 is the only session now, it will fast-foward state machine // to completion s1.Refresh(); // Completion callback should have been called once Assert.IsTrue(f.checkpointCallbackExpectation == 0); // We should be in REST, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 2), fht1.SystemState)); s1.Dispose(); RecoverAndTest(log); }
public void StateMachineTest6() { Prepare(out var f, out var s1, out var uc1, out var s2); // Suspend s1 uc1.SuspendThread(); // s1 is now in REST, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 1), SystemState.Make(s1.ctx.phase, s1.ctx.version))); // System should be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); // Since s2 is the only session now, it will fast-foward state machine // to completion s2.Refresh(); // We should be in REST, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 2), fht1.SystemState)); s2.Dispose(); fht1.TryInitiateHybridLogCheckpoint(out _, CheckpointType.FoldOver); fht1.CompleteCheckpointAsync().AsTask().GetAwaiter().GetResult(); // We should be in REST, 3 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 3), fht1.SystemState)); // Expect checkpoint completion callback on resume f.checkpointCallbackExpectation = 1; uc1.ResumeThread(); // Completion callback should have been called once Assert.AreEqual(0, f.checkpointCallbackExpectation); uc1.SuspendThread(); uc1.Dispose(); s1.Dispose(); RecoverAndTest(log); }
void Prepare(out SimpleFunctions f, out ClientSession <AdId, NumClicks, NumClicks, NumClicks, Empty, SimpleFunctions> s1, out ThreadSession <AdId, NumClicks, NumClicks, NumClicks, Empty, SimpleFunctions> s2) { f = new SimpleFunctions(); // We should be in REST, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 1), fht1.SystemState)); // Take index checkpoint for recovery purposes fht1.TakeIndexCheckpoint(out _); fht1.CompleteCheckpointAsync().GetAwaiter().GetResult(); // Index checkpoint does not update version, so // we should still be in REST, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 1), fht1.SystemState)); NumClicks value; s1 = fht1.For <NumClicks, NumClicks, Empty>().NewSession(f, "foo", threadAffinitized: true); for (int key = 0; key < numOps; key++) { value.numClicks = key; s1.Upsert(ref inputArray[key], ref value, Empty.Default, key); } // Ensure state machine needs no I/O wait during WAIT_FLUSH fht1.Log.ShiftReadOnlyAddress(fht1.Log.TailAddress, true); // Start affinitized session s2 on another thread for testing s2 = fht1.For <NumClicks, NumClicks, Empty>().CreateThreadSession(f, threadAffinized: true); // We should be in REST, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 1), fht1.SystemState)); fht1.TakeHybridLogCheckpoint(out _); // We should be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); }
public void StateMachineTest5() { Prepare(out var f, out var s1, out var s2); // We should be in PREPARE, 1 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PREPARE, 1), fht1.SystemState)); // Refresh session s2 s1.Refresh(); s2.Refresh(); // We should now be in IN_PROGRESS, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.IN_PROGRESS, 2), fht1.SystemState)); s1.Refresh(); // We should be in WAIT_PENDING, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.WAIT_PENDING, 2), fht1.SystemState)); s2.Refresh(); // We should be in WAIT_FLUSH, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.WAIT_FLUSH, 2), fht1.SystemState)); // Expect checkpoint completion callback f.checkpointCallbackExpectation = 1; s1.Refresh(); // Completion callback should have been called once Assert.IsTrue(f.checkpointCallbackExpectation == 0); // We should be in PERSISTENCE_CALLBACK, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.PERSISTENCE_CALLBACK, 2), fht1.SystemState)); // No callback here since already done s1.Refresh(); // Suspend s1 s1.UnsafeSuspendThread(); // Since s2 is the only session now, it will fast-foward state machine // to completion s2.Refresh(); // We should be in REST, 2 Assert.IsTrue(SystemState.Equal(SystemState.Make(Phase.REST, 2), fht1.SystemState)); // Expect no checkpoint completion callback on resume f.checkpointCallbackExpectation = 0; s1.UnsafeResumeThread(); // Completion callback should have been called once Assert.IsTrue(f.checkpointCallbackExpectation == 0); s2.Dispose(); s1.Dispose(); RecoverAndTest(log); }