Exemplo n.º 1
0
        internal static void TestPrepareUpdate(ActorStateTable stateTable, ReplicationUnit replicationUnit)
        {
            foreach (var actorStateDataWrapper in replicationUnit.ActorStateDataWrapperList)
            {
                TestLog(
                    "PrepareUpdate(SequenceNumber: {0}, Type: {1} Key: {2}, IsDelete: {3})",
                    replicationUnit.SequenceNumber,
                    actorStateDataWrapper.Type.ToString(),
                    actorStateDataWrapper.Key,
                    actorStateDataWrapper.IsDelete);
            }

            stateTable.PrepareUpdate(replicationUnit.ActorStateDataWrapperList, replicationUnit.SequenceNumber);
        }
Exemplo n.º 2
0
            internal static ReplicationUnit CreateForDeleteReminder(
                long sequenceNumber,
                string keyPrefix,
                int statesPerReplication)
            {
                var replicationUnit = new ReplicationUnit(sequenceNumber, ActorStateType.Reminder);

                for (int i = 1; i <= statesPerReplication; i++)
                {
                    replicationUnit.ActorStateDataWrapperList.Add(
                        CreateActorStateDataWrapperForDelete(ActorStateType.Reminder, keyPrefix + i));
                }

                return(replicationUnit);
            }
Exemplo n.º 3
0
            internal static ReplicationUnit CreateForUpdateTimeStamp(
                long sequenceNumber,
                string keyPrefix,
                int statesPerReplication,
                TimeSpan timeStamp)
            {
                var replicationUnit = new ReplicationUnit(sequenceNumber, ActorStateType.LogicalTimestamp);

                for (int i = 1; i <= statesPerReplication; i++)
                {
                    replicationUnit.ActorStateDataWrapperList.Add(CreateActorStateDataWrapper(keyPrefix + i, timeStamp));
                }

                return(replicationUnit);
            }
Exemplo n.º 4
0
            internal static ReplicationUnit CreateForUpdateActor(
                long sequenceNumber,
                string keyPrefix,
                int statesPerReplication,
                long dataLength)
            {
                var replicationUnit = new ReplicationUnit(sequenceNumber, ActorStateType.Actor);

                for (int i = 1; i <= statesPerReplication; i++)
                {
                    replicationUnit.ActorStateDataWrapperList.Add(CreateActorStateDataWrapper(keyPrefix + i, dataLength));
                }

                return(replicationUnit);
            }
Exemplo n.º 5
0
 internal static void TryReadAndVerify(
     ActorStateTable stateTable,
     ReplicationUnit replicationUnit,
     bool expectedResult,
     string expectedReminderName)
 {
     foreach (var actorStateDataWrapper in replicationUnit.ActorStateDataWrapperList)
     {
         TryReadAndVerify(
             stateTable,
             actorStateDataWrapper.Key,
             expectedResult,
             expectedReminderName);
     }
 }
Exemplo n.º 6
0
 internal static void TryReadAndVerify(
     ActorStateTable stateTable,
     ReplicationUnit replicationUnit,
     bool expectedResult,
     TimeSpan expectedTimestamp)
 {
     foreach (var actorStateDataWrapper in replicationUnit.ActorStateDataWrapperList)
     {
         TryReadAndVerify(
             stateTable,
             actorStateDataWrapper.Key,
             expectedResult,
             expectedTimestamp);
     }
 }
Exemplo n.º 7
0
        internal static void TestApply(ActorStateTable stateTable, ReplicationUnit replicationUnit, bool testLog = true)
        {
            if (testLog)
            {
                foreach (var actorStateDataWrapper in replicationUnit.ActorStateDataWrapperList)
                {
                    TestLog(
                        "Apply(SequenceNumber: {0}, Key: {1}, IsDelete: {2})",
                        replicationUnit.SequenceNumber,
                        actorStateDataWrapper.Key,
                        actorStateDataWrapper.IsDelete);
                }
            }

            replicationUnit.UpdateSequenceNumber();

            stateTable.ApplyUpdates(replicationUnit.ActorStateDataWrapperList);
        }
Exemplo n.º 8
0
        internal static void VerifyReads(
            ActorStateTable stateTable,
            ReplicationUnit replicationUnit,
            Dictionary <ActorStateType, int> statesPerReplication,
            bool expectedResult,
            long expectedLength,
            long expectedCommittedSequenceNumber,
            long expectedKnownSequenceNumber,
            long expectedCount)
        {
            VerifyStateTableSnapshot(
                stateTable,
                statesPerReplication,
                long.MaxValue,
                expectedCommittedSequenceNumber,
                expectedKnownSequenceNumber,
                expectedCount);

            TryReadAndVerify(stateTable, replicationUnit, expectedResult, expectedLength);
        }
Exemplo n.º 9
0
        internal static List <ReplicationUnit> GroupByRelicationUnit(ActorStateTable.ActorStateEnumerator enumerator)
        {
            var replicationUnits = new List <ReplicationUnit>();

            while (enumerator.PeekNext() != null)
            {
                var peek            = enumerator.PeekNext();
                var replicationUnit = new ReplicationUnit(peek.SequenceNumber, peek.Type);

                do
                {
                    replicationUnit.ActorStateDataWrapperList.Add(enumerator.GetNext());
                    peek = enumerator.PeekNext();
                }while (peek != null && peek.SequenceNumber == replicationUnit.SequenceNumber);

                replicationUnits.Add(replicationUnit);
            }

            return(replicationUnits);
        }
Exemplo n.º 10
0
        private void TestReplication(Dictionary <ActorStateType, int> statesPerReplication)
        {
            TestCase("### TestReplication ###");

            TestCase("### StatesPerReplication (Actor:{0}, TimeStamp:{1}, Reminder:{2}) ###",
                     statesPerReplication[ActorStateType.Actor],
                     statesPerReplication[ActorStateType.LogicalTimestamp],
                     statesPerReplication[ActorStateType.Reminder]);

            var maxReplicationMessageSize = 2048;
            var maxCopyMessageSize        = maxReplicationMessageSize / 2;

            var copyOrReplicationSerializer = VolatileActorStateProvider.CreateCopyOrReplicationOperationSerializer();

            var dataLength            = (maxCopyMessageSize / (3 * statesPerReplication[ActorStateType.Actor])) + 1;
            var primaryStateTable     = new ActorStateTable();
            var copyKeyPrefixs        = new string[] { "a", "b", "c", "d", "e" };
            var primarySequenceNumber = 0;

            var replicationUnitBatch = new List <ReplicationUnit>();
            var replicationUnitDict  = new Dictionary <string, ReplicationUnit>();

            foreach (var keyPrefix in copyKeyPrefixs)
            {
                var replicationUnit = ReplicationUnit.CreateForUpdateActor(
                    ++primarySequenceNumber,
                    keyPrefix,
                    statesPerReplication[ActorStateType.Actor],
                    dataLength);

                replicationUnitBatch.Add(replicationUnit);
                replicationUnitDict[keyPrefix] = replicationUnit;
            }

            TestApplyBatch(primaryStateTable, replicationUnitBatch);

            foreach (var keyPrefix in copyKeyPrefixs)
            {
                VerifyReads(
                    primaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    true,
                    dataLength,
                    primarySequenceNumber,
                    primarySequenceNumber,
                    primarySequenceNumber * statesPerReplication[ActorStateType.Actor]);
            }

            var copyStateEnumerator = new CopyStateEnumerator(
                primaryStateTable.GetShallowCopiesEnumerator(primarySequenceNumber),
                copyOrReplicationSerializer,
                primarySequenceNumber,
                maxCopyMessageSize);

            var replicationKeyPrefixes = new string[] { "w", "x", "y", "z" };

            replicationUnitBatch = new List <ReplicationUnit>();

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                var replicationUnit = ReplicationUnit.CreateForUpdateActor(
                    ++primarySequenceNumber,
                    keyPrefix,
                    statesPerReplication[ActorStateType.Actor],
                    dataLength);

                replicationUnitBatch.Add(replicationUnit);
                replicationUnitDict[keyPrefix] = replicationUnit;
            }

            var replicationData = TestApplyBatch(primaryStateTable, replicationUnitBatch);

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                VerifyReads(
                    primaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    true,
                    dataLength,
                    primarySequenceNumber,
                    primarySequenceNumber,
                    primarySequenceNumber * statesPerReplication[ActorStateType.Actor]);
            }

            var secondaryStateTable = new ActorStateTable();
            var stateReplicator     = new MockStateReplicator(
                copyOrReplicationSerializer,
                copyStateEnumerator,
                replicationData,
                Task.FromResult(true));

            var partition     = new Mock <IStatefulServicePartition>();
            var secondaryPump = new SecondaryPump(
                partition.Object,
                secondaryStateTable,
                stateReplicator,
                copyOrReplicationSerializer,
                new VolatileLogicalTimeManager(new MockSnapshotHandler(), TimeSpan.MaxValue),
                "SecondaryPumpUnitTest");

            TestCase("# TestReplication: Testcase 1: Pump replication operations");

            secondaryPump.StartReplicationPump();
            secondaryPump.WaitForPumpCompletionAsync().Wait();

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                VerifyReads(
                    secondaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    true,
                    dataLength,
                    primarySequenceNumber,
                    primarySequenceNumber,
                    replicationKeyPrefixes.Length * statesPerReplication[ActorStateType.Actor]);
            }

            TestCase("# Passed");
        }
Exemplo n.º 11
0
        private void TestCopyAndReplicationDelete(Dictionary <ActorStateType, int> statesPerReplication)
        {
            TestCase("### TestCopyAndReplicationDelete ###");

            TestCase("### StatesPerReplication (Actor:{0}, TimeStamp:{1}, Reminder:{2}) ###",
                     statesPerReplication[ActorStateType.Actor],
                     statesPerReplication[ActorStateType.LogicalTimestamp],
                     statesPerReplication[ActorStateType.Reminder]);

            var maxReplicationMessageSize = 2048;
            var maxCopyMessageSize        = maxReplicationMessageSize / 2;

            var copyOrReplicationSerializer = VolatileActorStateProvider.CreateCopyOrReplicationOperationSerializer();

            var dataLength            = (maxCopyMessageSize / (3 * statesPerReplication[ActorStateType.Actor])) + 1;
            var primaryStateTable     = new ActorStateTable();
            var copyKeyPrefixes       = new string[] { "a", "b", "c", "d", "e" };
            var primarySequenceNumber = 0;

            var replicationUnitBatch = new List <ReplicationUnit>();
            var replicationUnitDict  = new Dictionary <string, ReplicationUnit>();

            foreach (var keyPrefix in copyKeyPrefixes)
            {
                var replicationUnit = ReplicationUnit.CreateForUpdateActor(
                    ++primarySequenceNumber,
                    keyPrefix,
                    statesPerReplication[ActorStateType.Actor],
                    dataLength);

                replicationUnitBatch.Add(replicationUnit);
                replicationUnitDict[keyPrefix] = replicationUnit;
            }

            TestApplyBatch(primaryStateTable, replicationUnitBatch);

            foreach (var keyPrefix in copyKeyPrefixes)
            {
                VerifyReads(
                    primaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    true,
                    dataLength,
                    primarySequenceNumber,
                    primarySequenceNumber,
                    primarySequenceNumber * statesPerReplication[ActorStateType.Actor]);
            }

            var deletedCopyKeyPrefixes = new string[] { "a", "c", "e" };

            foreach (var keyPrefix in deletedCopyKeyPrefixes)
            {
                var replicationUnit = ReplicationUnit.CreateForDeleteActor(
                    ++primarySequenceNumber,
                    keyPrefix,
                    statesPerReplication[ActorStateType.Actor]);

                TestPrepareUpdate(primaryStateTable, replicationUnit);
                TestCommitUpdate(primaryStateTable, primarySequenceNumber);
            }

            var copyStateEnumerator = new CopyStateEnumerator(
                primaryStateTable.GetShallowCopiesEnumerator(primarySequenceNumber),
                copyOrReplicationSerializer,
                primarySequenceNumber,
                maxCopyMessageSize);

            var replicationKeyPrefixes = new string[] { "v", "w", "x", "y", "z" };

            replicationUnitBatch = new List <ReplicationUnit>();

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                var replicationUnit = ReplicationUnit.CreateForUpdateActor(
                    ++primarySequenceNumber,
                    keyPrefix,
                    statesPerReplication[ActorStateType.Actor],
                    dataLength);

                replicationUnitBatch.Add(replicationUnit);
                replicationUnitDict[keyPrefix] = replicationUnit;
            }

            var replicationData = TestApplyBatch(primaryStateTable, replicationUnitBatch);

            long expectedCount =
                (copyKeyPrefixes.Length
                 - deletedCopyKeyPrefixes.Length +
                 replicationKeyPrefixes.Length) *
                statesPerReplication[ActorStateType.Actor];

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                VerifyReads(
                    primaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    true,
                    dataLength,
                    primarySequenceNumber,
                    primarySequenceNumber,
                    expectedCount);
            }

            var deletedReplicationKeyPrefixes = new string[] { "v", "x", "z" };

            foreach (var keyPrefix in deletedReplicationKeyPrefixes)
            {
                var replicationUnit = ReplicationUnit.CreateForDeleteActor(
                    ++primarySequenceNumber,
                    keyPrefix,
                    statesPerReplication[ActorStateType.Actor]);

                TestPrepareUpdate(primaryStateTable, replicationUnit);
                TestCommitUpdate(primaryStateTable, primarySequenceNumber);

                replicationUnit.UpdateSequenceNumber();
                replicationData.Add(replicationUnit.ActorStateDataWrapperList);
            }

            var secondaryStateTable = new ActorStateTable();

            var replicationStreamReadySignal = new TaskCompletionSource <object>();
            var stateReplicator = new MockStateReplicator(
                copyOrReplicationSerializer,
                copyStateEnumerator,
                replicationData,
                replicationStreamReadySignal.Task);

            var partition     = new Mock <IStatefulServicePartition>();
            var secondaryPump = new SecondaryPump(
                partition.Object,
                secondaryStateTable,
                stateReplicator,
                copyOrReplicationSerializer,
                new VolatileLogicalTimeManager(new MockSnapshotHandler(), TimeSpan.MaxValue),
                "SecondaryPumpUnitTest");

            TestCase("# TestCopyAndReplicationDelete: Testcase 1: Pump copy and replication operations");

            secondaryPump.StartCopyAndReplicationPump();

            Task pumpCompletionTask = secondaryPump.WaitForPumpCompletionAsync();

            // Wait for copy pump to drain copy stream
            Thread.Sleep(TimeSpan.FromSeconds(5));

            FailTestIf(
                pumpCompletionTask.IsCompleted,
                "pumpCompletionTask.IsCompleted. Expected: false Actual: {0}.", pumpCompletionTask.IsCompleted);

            foreach (var keyPrefix in copyKeyPrefixes)
            {
                bool expectedExists = !deletedCopyKeyPrefixes.ToList().Exists(o => (o == keyPrefix));

                VerifyReads(
                    secondaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    expectedExists,
                    dataLength,
                    copyKeyPrefixes.Length + deletedCopyKeyPrefixes.Length,
                    copyKeyPrefixes.Length + deletedCopyKeyPrefixes.Length,
                    (copyKeyPrefixes.Length - deletedCopyKeyPrefixes.Length) * statesPerReplication[ActorStateType.Actor] + 1);
            }

            TestCase("# Signal replication stream to be ready.");
            replicationStreamReadySignal.SetResult(null);

            pumpCompletionTask.Wait();

            expectedCount =
                (copyKeyPrefixes.Length
                 + replicationKeyPrefixes.Length
                 - deletedCopyKeyPrefixes.Length
                 - deletedReplicationKeyPrefixes.Length)
                * statesPerReplication[ActorStateType.Actor] + 1;

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                bool expectedExists = !deletedReplicationKeyPrefixes.ToList().Exists(o => (o == keyPrefix));

                VerifyReads(
                    secondaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    expectedExists,
                    dataLength,
                    primarySequenceNumber,
                    primarySequenceNumber,
                    expectedCount);
            }

            TestCase("# TestCopyAndReplicationDelete: Testcase 2: Pump replication operations");

            secondaryPump.StartReplicationPump();
            secondaryPump.WaitForPumpCompletionAsync().Wait();

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                bool expectedExists = !deletedReplicationKeyPrefixes.ToList().Exists(o => (o == keyPrefix));

                VerifyReads(
                    secondaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    expectedExists,
                    dataLength,
                    primarySequenceNumber,
                    primarySequenceNumber,
                    expectedCount);
            }

            TestCase("# Passed");
        }
Exemplo n.º 12
0
        private void TestCopyUpToSequenceNumber(Dictionary <ActorStateType, int> statesPerReplication)
        {
            TestCase("### TestCopyUpToSequenceNumber ###");

            TestCase("### StatesPerReplication (Actor:{0}, TimeStamp:{1}, Reminder:{2}) ###",
                     statesPerReplication[ActorStateType.Actor],
                     statesPerReplication[ActorStateType.LogicalTimestamp],
                     statesPerReplication[ActorStateType.Reminder]);

            var maxReplicationMessageSize = 2048;
            var maxCopyMessageSize        = maxReplicationMessageSize / 2;

            var copyOrReplicationSerializer = VolatileActorStateProvider.CreateCopyOrReplicationOperationSerializer();

            var dataLength            = (maxCopyMessageSize / (3 * statesPerReplication[ActorStateType.Actor])) + 1;
            var primaryStateTable     = new ActorStateTable();
            var copyKeyPrefixes       = new string[] { "a", "b", "c", "d", "e" };
            var primarySequenceNumber = 0;

            var replicationUnitBatch = new List <ReplicationUnit>();
            var replicationUnitDict  = new Dictionary <string, ReplicationUnit>();

            foreach (var keyPrefix in copyKeyPrefixes)
            {
                var replicationUnit = ReplicationUnit.CreateForUpdateActor(
                    ++primarySequenceNumber,
                    keyPrefix,
                    statesPerReplication[ActorStateType.Actor],
                    dataLength);

                replicationUnitBatch.Add(replicationUnit);
                replicationUnitDict[keyPrefix] = replicationUnit;
            }

            TestApplyBatch(primaryStateTable, replicationUnitBatch);

            foreach (var keyPrefix in copyKeyPrefixes)
            {
                VerifyReads(
                    primaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    true,
                    dataLength,
                    primarySequenceNumber,
                    primarySequenceNumber,
                    primarySequenceNumber * statesPerReplication[ActorStateType.Actor]);
            }

            var replicationKeyPrefixes = new string[] { "w", "x", "y", "z" };

            replicationUnitBatch = new List <ReplicationUnit>();

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                var replicationUnit = ReplicationUnit.CreateForUpdateActor(
                    ++primarySequenceNumber,
                    keyPrefix,
                    statesPerReplication[ActorStateType.Actor],
                    dataLength);

                replicationUnitBatch.Add(replicationUnit);
                replicationUnitDict[keyPrefix] = replicationUnit;
            }

            TestApplyBatch(primaryStateTable, replicationUnitBatch);

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                VerifyReads(
                    primaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    true,
                    dataLength,
                    primarySequenceNumber,
                    primarySequenceNumber,
                    primarySequenceNumber * statesPerReplication[ActorStateType.Actor]);
            }

            var upToSequenceNumber  = copyKeyPrefixes.Length + replicationKeyPrefixes.Length / 2;
            var copyStateEnumerator = new CopyStateEnumerator(
                primaryStateTable.GetShallowCopiesEnumerator(upToSequenceNumber),
                copyOrReplicationSerializer,
                upToSequenceNumber,
                maxCopyMessageSize);

            var secondaryStateTable = new ActorStateTable();

            var replicationStreamReadySignal = new TaskCompletionSource <object>();
            var stateReplicator = new MockStateReplicator(
                copyOrReplicationSerializer,
                copyStateEnumerator,
                new List <List <ActorStateDataWrapper> >(),
                replicationStreamReadySignal.Task);

            var partition     = new Mock <IStatefulServicePartition>();
            var secondaryPump = new SecondaryPump(
                partition.Object,
                secondaryStateTable,
                stateReplicator,
                copyOrReplicationSerializer,
                new VolatileLogicalTimeManager(new MockSnapshotHandler(), TimeSpan.MaxValue),
                "SecondaryPumpUnitTest");

            TestCase("# TestCopyUpToSequenceNumber: Testcase 1: Pump copy operations");

            secondaryPump.StartCopyAndReplicationPump();

            Task pumpCompletionTask = secondaryPump.WaitForPumpCompletionAsync();

            Thread.Sleep(TimeSpan.FromSeconds(5));

            FailTestIf(
                pumpCompletionTask.IsCompleted,
                "Pump CopyAndReplicationTask completed before replication stream is ready.");

            foreach (var keyPrefix in copyKeyPrefixes)
            {
                VerifyReads(
                    secondaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    true,
                    dataLength,
                    upToSequenceNumber,
                    upToSequenceNumber,
                    upToSequenceNumber * statesPerReplication[ActorStateType.Actor]);
            }

            TestCase("# Signal replication stream to be ready.");
            replicationStreamReadySignal.SetResult(null);

            pumpCompletionTask.Wait();

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                VerifyReads(
                    secondaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    (keyPrefix == "w" || keyPrefix == "x") ? true : false,
                    dataLength,
                    upToSequenceNumber,
                    upToSequenceNumber,
                    upToSequenceNumber * statesPerReplication[ActorStateType.Actor]);
            }

            TestCase("# TestCopyUpToSequenceNumber: Testcase 2: Pump replication operations (none)");

            secondaryPump.StartReplicationPump();
            secondaryPump.WaitForPumpCompletionAsync().Wait();

            foreach (var keyPrefix in replicationKeyPrefixes)
            {
                VerifyReads(
                    secondaryStateTable,
                    replicationUnitDict[keyPrefix],
                    statesPerReplication,
                    (keyPrefix == "w" || keyPrefix == "x") ? true : false,
                    dataLength,
                    upToSequenceNumber,
                    upToSequenceNumber,
                    upToSequenceNumber * statesPerReplication[ActorStateType.Actor]);
            }

            TestCase("# Passed");
        }