internal static IActorStateProvider CreateDefaultStateProvider(ActorTypeInformation actorTypeInfo)
        {
            // KvsActorStateProvider is used only when:
            //    1. Actor's [StatePersistenceAttribute] attribute has StatePersistence.Persisted.
            // VolatileActorStateProvider is used when:
            //    1. Actor's [StatePersistenceAttribute] attribute has StatePersistence.Volatile
            // NullActorStateProvider is used when:
            //    2. Actor's [StatePersistenceAttribute] attribute has StatePersistence.None OR
            //    3. Actor doesn't have [StatePersistenceAttribute] attribute.

            IActorStateProvider stateProvider = new NullActorStateProvider();

            if (actorTypeInfo.StatePersistence.Equals(StatePersistence.Persisted))
            {
                stateProvider = new KvsActorStateProvider();
            }
            else if (actorTypeInfo.StatePersistence.Equals(StatePersistence.Volatile))
            {
                stateProvider = new VolatileActorStateProvider();
            }

            // Get state provider override from settings if specified, used by tests to override state providers.
            var stateProviderOverride = GetActorStateProviderOverride();

            if (stateProviderOverride != null)
            {
                stateProvider = stateProviderOverride;
            }

            return(stateProvider);
        }
Beispiel #2
0
            async Task <IOperation> IOperationStream.GetOperationAsync(System.Threading.CancellationToken cancellationToken)
            {
                await this._replicationStreamReadySignal;

                if (this._replicationDataIndex < this._replicationData.Count)
                {
                    var actorStateDataWrapperList = this._replicationData[this._replicationDataIndex++];
                    var replicationSequenceNumber = actorStateDataWrapperList[0].SequenceNumber;
                    var replicationOperation      = new VolatileActorStateProvider.CopyOrReplicationOperation(actorStateDataWrapperList);

                    // Secondary pump should take sequence number off the replication operation
                    // rather than the data
                    //
                    foreach (var actorStateDataWrapper in actorStateDataWrapperList)
                    {
                        actorStateDataWrapper.UpdateSequenceNumber(0);
                    }

                    return(new MockOperation(
                               VolatileActorStateProvider.SerializeToOperationData(
                                   this._replicationSerializer,
                                   replicationOperation),
                               replicationSequenceNumber));
                }

                return(null);
            }
Beispiel #3
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");
        }
Beispiel #4
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");
        }
Beispiel #5
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");
        }