예제 #1
0
        public void AsyncPipelineSimpleTest()
        {
            int       step     = 1000;
            var       done     = TimedCompletions(step, step, step);
            var       pipeline = new AsyncPipeline(2);
            Stopwatch watch    = new Stopwatch();

            watch.Start();
            pipeline.Add(done[0]);
            const int epsilon  = 100;
            var       elapsed0 = watch.ElapsedMilliseconds;

            Assert.IsTrue(elapsed0 < epsilon, elapsed0.ToString());
            pipeline.Add(done[2]);
            var elapsed1 = watch.ElapsedMilliseconds;

            Assert.IsTrue(elapsed1 < epsilon, elapsed1.ToString());
            pipeline.Add(done[1]);
            var elapsed2 = watch.ElapsedMilliseconds;

            Assert.IsTrue(step - epsilon <= elapsed2 && elapsed2 <= step + epsilon);
            pipeline.Wait();
            watch.Stop();
            Assert.IsTrue(3 * step - epsilon <= watch.ElapsedMilliseconds && watch.ElapsedMilliseconds <= 3 * step + epsilon);
        }
예제 #2
0
        public void AsyncPipelineWaitTest()
        {
            Random rand = new Random(222);
            int started = 0;
            int finished1 = 0;
            int finished2 = 0;
            int numActions = 1000;
            Action action1 = (() => 
                {
                    lock (this) started++;
                    Thread.Sleep((int)(rand.NextDouble() * 100));
                    lock (this) finished1++;
                });
            Action action2 = (() =>
            {
                Thread.Sleep((int)(rand.NextDouble() * 100));
                lock (this) finished2++;
            });

            var pipeline = new AsyncPipeline(10);
            for (int i = 0; i < numActions; i++)
            {
                var async1 = Task.Run(action1);
                pipeline.Add(async1);
                var async2 = async1.ContinueWith(_ => action2());
                pipeline.Add(async2);
            }
            pipeline.Wait();
            Assert.AreEqual(numActions, started);
            Assert.AreEqual(numActions, finished1);
            Assert.AreEqual(numActions, finished2);
        }
예제 #3
0
        public void AsyncPipelineWaitTest()
        {
            Random rand       = new Random(222);
            int    started    = 0;
            int    finished1  = 0;
            int    finished2  = 0;
            int    numActions = 1000;
            Action action1    = (() =>
            {
                lock (this) started++;
                Thread.Sleep((int)(rand.NextDouble() * 100));
                lock (this) finished1++;
            });
            Action action2 = (() =>
            {
                Thread.Sleep((int)(rand.NextDouble() * 100));
                lock (this) finished2++;
            });

            var pipeline = new AsyncPipeline(10);

            for (int i = 0; i < numActions; i++)
            {
                var async1 = Task.Run(action1);
                pipeline.Add(async1);
                var async2 = async1.ContinueWith(_ => action2());
                pipeline.Add(async2);
            }
            pipeline.Wait();
            Assert.AreEqual(numActions, started);
            Assert.AreEqual(numActions, finished1);
            Assert.AreEqual(numActions, finished2);
        }
예제 #4
0
        public void AsyncPipelineSimpleTest()
        {
            int       step     = 2000;
            int       epsilon  = 200;
            var       pipeline = new AsyncPipeline(2);
            var       done     = TimedCompletions(step, step, step);
            Stopwatch watch    = Stopwatch.StartNew();

            pipeline.Add(done[0]);
            var elapsed0 = watch.ElapsedMilliseconds;

            Assert.True(elapsed0 < epsilon, $"{elapsed0}ms");
            pipeline.Add(done[2]);
            var elapsed1 = watch.ElapsedMilliseconds;

            Assert.True(elapsed1 < epsilon, $"{elapsed1}ms");
            pipeline.Add(done[1]);
            var elapsed2 = watch.ElapsedMilliseconds;

            Assert.True(step - epsilon <= elapsed2, $"{elapsed2}ms");
            Assert.True(elapsed2 <= step + epsilon, $"{elapsed2}ms");
            pipeline.Wait();
            watch.Stop();
            Assert.True(3 * step - epsilon <= watch.ElapsedMilliseconds, $"{watch.ElapsedMilliseconds}ms");
            Assert.True(watch.ElapsedMilliseconds <= 3 * step + epsilon, $"{watch.ElapsedMilliseconds}ms");
        }
예제 #5
0
        private Task Test_Stream_Churn_NumStreams(
            string streamProviderName,
            int pipelineSize,
            int numStreams,
            int numConsumers          = 9,
            int numProducers          = 1,
            bool warmUpPubSub         = true,
            bool normalSubscribeCalls = true)
        {
            output.WriteLine("Testing churn with {0} Streams with {1} Consumers and {2} Producers per Stream NormalSubscribe={3}",
                             numStreams, numConsumers, numProducers, normalSubscribeCalls);

            AsyncPipeline pipeline = new AsyncPipeline(pipelineSize);
            var           promises = new List <Task>();

            // Create streamId Guids
            Guid[] streamIds = new Guid[numStreams];
            for (int i = 0; i < numStreams; i++)
            {
                streamIds[i] = Guid.NewGuid();
            }

            if (warmUpPubSub)
            {
                WarmUpPubSub(streamProviderName, streamIds, pipeline);

                pipeline.Wait();

                int activePubSubGrains = ActiveGrainCount(typeof(PubSubRendezvousGrain).FullName);
                Assert.Equal(streamIds.Length, activePubSubGrains);   //  "Initial PubSub count -- should all be warmed up"
            }

            int activeConsumerGrains = ActiveGrainCount(typeof(StreamLifecycleConsumerGrain).FullName);

            Assert.Equal(0, activeConsumerGrains);   //  "Initial Consumer count should be zero"

            Stopwatch sw = Stopwatch.StartNew();

            for (int i = 0; i < numStreams; i++)
            {
                Task promise = SetupOneStream(streamIds[i], streamProviderName, pipeline, numConsumers, numProducers, normalSubscribeCalls);
                promises.Add(promise);
            }
            Task.WhenAll(promises).Wait();
            sw.Stop();

            int consumerCount = ActiveGrainCount(typeof(StreamLifecycleConsumerGrain).FullName);

            Assert.Equal(activeConsumerGrains + (numStreams * numConsumers), consumerCount);   //  "The correct number of new Consumer grains are active"

            TimeSpan elapsed            = sw.Elapsed;
            int      totalSubscriptions = numStreams * numConsumers;
            double   rps = totalSubscriptions / elapsed.TotalSeconds;

            output.WriteLine("Subscriptions-per-second = {0} during period {1}", rps, elapsed);
            Assert.NotEqual(0.0, rps);   // "RPS greater than zero"
            return(Task.CompletedTask);
        }
        public async Task DeactivateOnIdleTest_Stress_3_MayInterleave_With_TaskCompletionSource_UnderConstantLoad()
        {
            foreach (var i in Enumerable.Range(0, 100))
            {
                Initialize();

                output.WriteLine($"Running test #{i}");
                await RunTest();

                Dispose();
            }

            async Task RunTest()
            {
                var a = this.testCluster.GrainFactory.GetGrain <ICollectionTestGrain>(1, "UnitTests.Grains.MayInterleaveCollectionTestGrainWithTcs");

                var activated = await a.GetActivationTime();

                Assert.Equal(activated, await a.GetActivationTime());

                var pipeline     = new AsyncPipeline(20);
                var cts          = new CancellationTokenSource();
                var cancellation = cts.Token;

                var requests = new List <Task <int> >();
                var senders  = Task.Run(() =>
                {
                    while (!cancellation.IsCancellationRequested)
                    {
                        var request = a.IncrCounter();
                        requests.Add(request);
                        pipeline.Add(request);
                    }
                });

                // give it some time to fill the queue
                await Task.Delay(TimeSpan.FromSeconds(1));

                output.WriteLine($"Requests (before): {requests.Count}");
                await a.DeactivateSelf();

                cts.Cancel();
                pipeline.Wait();
                await senders;

                output.WriteLine("After deactivation");
                Assert.NotEqual(activated, await a.GetActivationTime());

                output.WriteLine($"Requests (total): {requests.Count}");
                Assert.All(requests, x => Assert.True(x.Status == TaskStatus.RanToCompletion));
            }
        }
예제 #7
0
        private void ForEachUser(Action <IChirperAccount> action)
        {
            List <Task> promises = new List <Task>();

            foreach (long userId in loader.Users.Keys)
            {
                IChirperAccount user = loader.Users[userId];
                Task            p    = Task.Factory.StartNew(() => action(user));
                pipeline.Add(p);
                promises.Add(p);
            }
            pipeline.Wait();
            Task.WhenAll(promises).Wait();
        }
예제 #8
0
        //private async Task Test_Stream_Churn_TimePeriod(
        //    string streamProviderName,
        //    int pipelineSize,
        //    TimeSpan duration,
        //    int numConsumers = 9,
        //    int numProducers = 1)
        //{
        //    output.WriteLine("Testing Subscription churn for duration {0} with {1} Consumers and {2} Producers per Stream",
        //        duration, numConsumers, numProducers);

        //    AsyncPipeline pipeline = new AsyncPipeline(pipelineSize);
        //    var promises = new List<Task>();

        //    Stopwatch sw = Stopwatch.StartNew();

        //    for (int i = 0; sw.Elapsed <= duration; i++)
        //    {
        //        Guid streamId = Guid.NewGuid();
        //        Task promise = SetupOneStream(streamId, streamProviderName, pipeline, numConsumers, numProducers);
        //        promises.Add(promise);
        //    }
        //    await Task.WhenAll(promises);
        //    sw.Stop();
        //    TimeSpan elapsed = sw.Elapsed;
        //    int totalSubscription = numSt* numConsumers);
        //    double rps = totalSubscription/elapsed.TotalSeconds;
        //    output.WriteLine("Subscriptions-per-second = {0} during period {1}", rps, elapsed);
        //    Assert.NotEqual(0.0, rps, "RPS greater than zero");
        //}

        private void WarmUpPubSub(string streamProviderName, StreamId[] streamIds, AsyncPipeline pipeline)
        {
            int numStreams = streamIds.Length;

            // Warm up PubSub for the appropriate streams
            for (int i = 0; i < numStreams; i++)
            {
                var streamId = new InternalStreamId(streamProviderName, streamIds[i]);
                _ = streamProviderName + "_" + this.StreamNamespace;

                IPubSubRendezvousGrain pubsub = this.GrainFactory.GetGrain <IPubSubRendezvousGrain>(streamId.ToString());

                Task promise = pubsub.Validate();

                pipeline.Add(promise);
            }
            pipeline.Wait();
        }
예제 #9
0
        //private async Task Test_Stream_Churn_TimePeriod(
        //    string streamProviderName,
        //    int pipelineSize,
        //    TimeSpan duration,
        //    int numConsumers = 9,
        //    int numProducers = 1)
        //{
        //    output.WriteLine("Testing Subscription churn for duration {0} with {1} Consumers and {2} Producers per Stream",
        //        duration, numConsumers, numProducers);

        //    AsyncPipeline pipeline = new AsyncPipeline(pipelineSize);
        //    var promises = new List<Task>();

        //    Stopwatch sw = Stopwatch.StartNew();

        //    for (int i = 0; sw.Elapsed <= duration; i++)
        //    {
        //        Guid streamId = Guid.NewGuid();
        //        Task promise = SetupOneStream(streamId, streamProviderName, pipeline, numConsumers, numProducers);
        //        promises.Add(promise);
        //    }
        //    await Task.WhenAll(promises);
        //    sw.Stop();
        //    TimeSpan elapsed = sw.Elapsed;
        //    int totalSubscription = numSt* numConsumers);
        //    double rps = totalSubscription/elapsed.TotalSeconds;
        //    output.WriteLine("Subscriptions-per-second = {0} during period {1}", rps, elapsed);
        //    Assert.NotEqual(0.0, rps, "RPS greater than zero");
        //}

        private void WarmUpPubSub(string streamProviderName, Guid[] streamIds, AsyncPipeline pipeline)
        {
            int numStreams = streamIds.Length;

            // Warm up PubSub for the appropriate streams
            for (int i = 0; i < numStreams; i++)
            {
                Guid   streamId = streamIds[i];
                string extKey   = streamProviderName + "_" + this.StreamNamespace;

                IPubSubRendezvousGrain pubsub = this.GrainFactory.GetGrain <IPubSubRendezvousGrain>(streamId, extKey, null);

                Task promise = pubsub.Validate();

                pipeline.Add(promise);
            }
            pipeline.Wait();
        }
예제 #10
0
 public void AsyncPipelineSimpleTest()
 {
     int step = 1000;
     var done = TimedCompletions(step, step, step);
     var pipeline = new AsyncPipeline(2);
     Stopwatch watch = new Stopwatch();
     watch.Start();
     pipeline.Add(done[0]);
     const int epsilon = 100;
     var elapsed0 = watch.ElapsedMilliseconds;
     Assert.IsTrue(elapsed0 < epsilon, elapsed0.ToString());
     pipeline.Add(done[2]);
     var elapsed1 = watch.ElapsedMilliseconds;
     Assert.IsTrue(elapsed1 < epsilon, elapsed1.ToString());
     pipeline.Add(done[1]);
     var elapsed2 = watch.ElapsedMilliseconds;
     Assert.IsTrue(step - epsilon <= elapsed2 && elapsed2 <= step + epsilon);
     pipeline.Wait();
     watch.Stop();
     Assert.IsTrue(3 * step - epsilon <= watch.ElapsedMilliseconds && watch.ElapsedMilliseconds <= 3 * step + epsilon);
 }
예제 #11
0
        private Task Test_Stream_Churn_NumStreams_FewPublishers(
            string streamProviderName,
            int pipelineSize,
            int numStreams,
            int numConsumers          = 9,
            int numProducers          = 4,
            bool warmUpPubSub         = true,
            bool warmUpProducers      = false,
            bool normalSubscribeCalls = true)
        {
            output.WriteLine("Testing churn with {0} Streams on {1} Producers with {2} Consumers per Stream",
                             numStreams, numProducers, numConsumers);

            AsyncPipeline pipeline = new AsyncPipeline(pipelineSize);

            // Create streamId Guids
            Guid[] streamIds = new Guid[numStreams];
            for (int i = 0; i < numStreams; i++)
            {
                streamIds[i] = Guid.NewGuid();
            }

            int activeConsumerGrains = ActiveGrainCount(typeof(StreamLifecycleConsumerGrain).FullName);

            Assert.Equal(0, activeConsumerGrains);   //  "Initial Consumer count should be zero"
            int activeProducerGrains = ActiveGrainCount(typeof(StreamLifecycleProducerGrain).FullName);

            Assert.Equal(0, activeProducerGrains);   //  "Initial Producer count should be zero"

            if (warmUpPubSub)
            {
                WarmUpPubSub(streamProviderName, streamIds, pipeline);

                pipeline.Wait();

                int activePubSubGrains = ActiveGrainCount(typeof(PubSubRendezvousGrain).FullName);
                Assert.Equal(streamIds.Length, activePubSubGrains);   //  "Initial PubSub count -- should all be warmed up"
            }

            Guid[] producerIds = new Guid[numProducers];

            if (numProducers > 0 && warmUpProducers)
            {
                // Warm up Producers to pre-create grains
                for (int i = 0; i < numProducers; i++)
                {
                    producerIds[i] = Guid.NewGuid();
                    var  grain   = this.GrainFactory.GetGrain <IStreamLifecycleProducerGrain>(producerIds[i]);
                    Task promise = grain.Ping();

                    pipeline.Add(promise);
                }
                pipeline.Wait();

                int activePublisherGrains = this.ActiveGrainCount(typeof(StreamLifecycleProducerGrain).FullName);
                Assert.Equal(numProducers, activePublisherGrains);   //  "Initial Publisher count -- should all be warmed up"
            }

            var promises = new List <Task>();

            Stopwatch sw = Stopwatch.StartNew();

            if (numProducers > 0)
            {
                // Producers
                for (int i = 0; i < numStreams; i++)
                {
                    Guid streamId   = streamIds[i];
                    Guid producerId = producerIds[i % numProducers];
                    var  grain      = this.GrainFactory.GetGrain <IStreamLifecycleProducerGrain>(producerId);

                    Task promise = grain.BecomeProducer(streamId, this.StreamNamespace, streamProviderName);

                    promises.Add(promise);
                    pipeline.Add(promise);
                }
                pipeline.Wait();
                promises.Clear();
            }

            // Consumers
            for (int i = 0; i < numStreams; i++)
            {
                Guid streamId = streamIds[i];

                Task promise = SetupOneStream(streamId, streamProviderName, pipeline, numConsumers, 0, normalSubscribeCalls);
                promises.Add(promise);
            }
            pipeline.Wait();

            Task.WhenAll(promises).Wait();
            sw.Stop();

            int consumerCount = ActiveGrainCount(typeof(StreamLifecycleConsumerGrain).FullName);

            Assert.Equal(activeConsumerGrains + (numStreams * numConsumers), consumerCount);   //  "The right number of Consumer grains are active"

            int producerCount = ActiveGrainCount(typeof(StreamLifecycleProducerGrain).FullName);

            Assert.Equal(activeProducerGrains + (numStreams * numProducers), producerCount);   //  "The right number of Producer grains are active"

            int pubSubCount = ActiveGrainCount(typeof(PubSubRendezvousGrain).FullName);

            Assert.Equal(streamIds.Length, pubSubCount);   //  "Final PubSub count -- no more started"

            TimeSpan elapsed            = sw.Elapsed;
            int      totalSubscriptions = numStreams * numConsumers;
            double   rps = totalSubscriptions / elapsed.TotalSeconds;

            output.WriteLine("Subscriptions-per-second = {0} during period {1}", rps, elapsed);
            Assert.NotEqual(0.0, rps);   // "RPS greater than zero"
            return(Task.CompletedTask);
        }
예제 #12
0
        private async Task AsyncPipelineBlackBoxConsistencyTest(int workerCount)
        {
            if (workerCount < 1)
                throw new ArgumentOutOfRangeException("You must specify at least one worker.", "workerCount");

            int loopCount = _iterationCount / workerCount;
            const double variance = 0.1;
            int expectedTasksCompleted = loopCount * workerCount;
            var delayLength = TimeSpan.FromSeconds(1);
            const int pipelineCapacity = _defaultPipelineCapacity;
            var pipeline = new AsyncPipeline(pipelineCapacity);
            int tasksCompleted = 0;
            // the following value is wrapped within an array to avoid a modified closure warning from ReSharper.
            int[] pipelineSize = { 0 };
            var capacityReached = new InterlockedFlag();

            Action workFunc =
                () =>
                {
                    var sz = Interlocked.Increment(ref pipelineSize[0]);
                    CheckPipelineState(sz, pipelineCapacity, capacityReached);
                    Task.Delay(delayLength).Wait();
                    Interlocked.Decrement(ref pipelineSize[0]);
                    Interlocked.Increment(ref tasksCompleted);
                };

            Action workerFunc =
                () =>
                {
                    for (var j = 0; j < loopCount; j++)
                    {
                        Task task = new Task(workFunc);
                        pipeline.Add(task, whiteBox: null);
                        task.Start();
                    }
                };

            Func<Task> monitorFunc =
                async () =>
                {
                    var delay = TimeSpan.FromSeconds(5);
                    while (tasksCompleted < expectedTasksCompleted)
                    {
                        output.WriteLine("test in progress: tasksCompleted = {0}.", tasksCompleted);
                        await Task.Delay(delay);
                    }
                };

            var workers = new Task[workerCount];
            var stopwatch = Stopwatch.StartNew();
            for (var i = 0; i < workerCount; ++i)
                workers[i] = Task.Run(workerFunc);
            Task.Run(monitorFunc).Ignore();
            await Task.WhenAll(workers);
            pipeline.Wait();
            stopwatch.Stop();
            Assert.AreEqual(expectedTasksCompleted, tasksCompleted, "The test did not complete the expected number of tasks.");

            var targetTimeSec = expectedTasksCompleted * delayLength.TotalSeconds / pipelineCapacity;
            var minTimeSec = (1.0 - variance) * targetTimeSec;
            var maxTimeSec = (1.0 + variance) * targetTimeSec;
            var actualSec = stopwatch.Elapsed.TotalSeconds;
            output.WriteLine(
                "Test finished in {0} sec, {1}% of target time {2} sec. Permitted variance is +/-{3}%",
                actualSec,
                actualSec / targetTimeSec * 100,
                targetTimeSec,
                variance * 100);

            Assert.IsTrue(capacityReached.IsSet, "Pipeline capacity not reached; the delay length probably is too short to be useful.");
            Assert.IsTrue(
                actualSec >= minTimeSec, 
                string.Format("The unit test completed too early ({0} sec < {1} sec).", actualSec, minTimeSec));
            Assert.IsTrue(
                actualSec <= maxTimeSec, 
                string.Format("The unit test completed too late ({0} sec > {1} sec).", actualSec, maxTimeSec));
        }
예제 #13
0
        private static async Task InitializeTopology(Guid streamId, string streamNamespace, string streamProviderName,
            int numProducers, int numConsumers,
            List<IStreamLifecycleProducerGrain> producers, List<IStreamLifecycleConsumerGrain> consumers,
            bool useFanOut)
        {
            long nextGrainId = random.Next();

            //var promises = new List<Task>();
            AsyncPipeline pipeline = new AsyncPipeline(InitPipelineSize);

            // Consumers
            long consumerIdStart = nextGrainId;
            for (int loopCount = 0; loopCount < numConsumers; loopCount++)
            {
                var grain = GrainClient.GrainFactory.GetGrain<IStreamLifecycleConsumerGrain>(Guid.NewGuid());
                consumers.Add(grain);

                Task promise = grain.BecomeConsumer(streamId, streamNamespace, streamProviderName);

                if (useFanOut)
                {
                    pipeline.Add(promise);
                    //promises.Add(promise);

                    //if (loopCount%WaitBatchSize == 0)
                    //{
                    //    Console.WriteLine("InitializeTopology: Waiting for {0} consumers to initialize", promises.Count);
                    //    await Task.WhenAll(promises);
                    //    promises.Clear();
                    //}
                }
                else
                {
                    await promise;
                }
            }
            if (useFanOut)
            {
                //Console.WriteLine("InitializeTopology: Waiting for {0} consumers to initialize", promises.Count);
                //await Task.WhenAll(promises);
                //promises.Clear();
                //Console.WriteLine("InitializeTopology: Waiting for {0} consumers to initialize", pipeline.Count);
                pipeline.Wait();
            }
            nextGrainId += numConsumers;

            // Producers
            long producerIdStart = nextGrainId;
            pipeline = new AsyncPipeline(InitPipelineSize);
            for (int loopCount = 0; loopCount < numProducers; loopCount++)
            {
                var grain = GrainClient.GrainFactory.GetGrain<IStreamLifecycleProducerGrain>(Guid.NewGuid());
                producers.Add(grain);

                Task promise = grain.BecomeProducer(streamId, streamNamespace, streamProviderName);

                if (useFanOut)
                {
                    pipeline.Add(promise);
                    //promises.Add(promise);
                }
                else
                {
                    await promise;
                }
            }
            if (useFanOut)
            {
                //Console.WriteLine("InitializeTopology: Waiting for {0} producers to initialize", promises.Count);
                //await Task.WhenAll(promises);
                //promises.Clear();
                //Console.WriteLine("InitializeTopology: Waiting for {0} producers to initialize", pipeline.Count);
                pipeline.Wait();
            }
            //nextGrainId += numProducers;
        }
예제 #14
0
        private Task Test_Stream_Churn_NumStreams(
            string streamProviderName,
            int pipelineSize,
            int numStreams,
            int numConsumers = 9,
            int numProducers = 1,
            bool warmUpPubSub = true,
            bool normalSubscribeCalls = true)
        {
            Console.WriteLine("Testing churn with {0} Streams with {1} Consumers and {2} Producers per Stream NormalSubscribe={3}",
                numStreams, numConsumers, numProducers, normalSubscribeCalls);

            AsyncPipeline pipeline = new AsyncPipeline(pipelineSize);
            var promises = new List<Task>();

            // Create streamId Guids
            Guid[] streamIds = new Guid[numStreams];
            for (int i = 0; i < numStreams; i++)
            {
                streamIds[i] = Guid.NewGuid();
            }

            if (warmUpPubSub)
            {
                WarmUpPubSub(streamProviderName, streamIds, pipeline);

                pipeline.Wait();

                int activePubSubGrains = ActiveGrainCount(typeof(PubSubRendezvousGrain).FullName);
                Assert.AreEqual(streamIds.Length, activePubSubGrains, "Initial PubSub count -- should all be warmed up");
            }
            
            int activeConsumerGrains = ActiveGrainCount(typeof(StreamLifecycleConsumerGrain).FullName);
            Assert.AreEqual(0, activeConsumerGrains, "Initial Consumer count should be zero");

            Stopwatch sw = Stopwatch.StartNew();

            for (int i = 0; i < numStreams; i++)
            {
                Task promise = SetupOneStream(streamIds[i], streamProviderName, pipeline, numConsumers, numProducers, normalSubscribeCalls);
                promises.Add(promise);
            }
            Task.WhenAll(promises).Wait();
            sw.Stop();

            int consumerCount = ActiveGrainCount(typeof(StreamLifecycleConsumerGrain).FullName);
            Assert.AreEqual(activeConsumerGrains + (numStreams * numConsumers), consumerCount, "The correct number of new Consumer grains are active");

            TimeSpan elapsed = sw.Elapsed;
            int totalSubscriptions = numStreams * numConsumers;
            double rps = totalSubscriptions / elapsed.TotalSeconds;
            Console.WriteLine("Subscriptions-per-second = {0} during period {1}", rps, elapsed);
            Assert.AreNotEqual(0.0, rps, "RPS greater than zero");
            return TaskDone.Done;
        }
예제 #15
0
        private Task Test_Stream_Churn_NumStreams_FewPublishers(
            string streamProviderName,
            int pipelineSize,
            int numStreams,
            int numConsumers = 9,
            int numProducers = 4,
            bool warmUpPubSub = true,
            bool warmUpProducers = false,
            bool normalSubscribeCalls = true)
        {
            Console.WriteLine("Testing churn with {0} Streams on {1} Producers with {2} Consumers per Stream",
                numStreams, numProducers, numConsumers);

            AsyncPipeline pipeline = new AsyncPipeline(pipelineSize);

            // Create streamId Guids
            Guid[] streamIds = new Guid[numStreams];
            for (int i = 0; i < numStreams; i++)
            {
                streamIds[i] = Guid.NewGuid();
            }

            int activeConsumerGrains = ActiveGrainCount(typeof(StreamLifecycleConsumerGrain).FullName);
            Assert.AreEqual(0, activeConsumerGrains, "Initial Consumer count should be zero");
            int activeProducerGrains = ActiveGrainCount(typeof(StreamLifecycleProducerGrain).FullName);
            Assert.AreEqual(0, activeProducerGrains, "Initial Producer count should be zero");

            if (warmUpPubSub)
            {
                WarmUpPubSub(streamProviderName, streamIds, pipeline);

                pipeline.Wait();

                int activePubSubGrains = ActiveGrainCount(typeof(PubSubRendezvousGrain).FullName);
                Assert.AreEqual(streamIds.Length, activePubSubGrains, "Initial PubSub count -- should all be warmed up");
            }

            Guid[] producerIds = new Guid[numProducers];

            if (numProducers > 0 && warmUpProducers)
            {
                // Warm up Producers to pre-create grains
                for (int i = 0; i < numProducers; i++)
                {
                    producerIds[i] = Guid.NewGuid();
                    var grain = GrainClient.GrainFactory.GetGrain<IStreamLifecycleProducerGrain>(producerIds[i]);
                    Task promise = grain.Ping();

                    pipeline.Add(promise);
                }
                pipeline.Wait();

                int activePublisherGrains = ActiveGrainCount(typeof(StreamLifecycleProducerGrain).FullName);
                Assert.AreEqual(numProducers, activePublisherGrains, "Initial Publisher count -- should all be warmed up");
            }

            var promises = new List<Task>();

            Stopwatch sw = Stopwatch.StartNew();

            if (numProducers > 0)
            {
                // Producers
                for (int i = 0; i < numStreams; i++)
                {
                    Guid streamId = streamIds[i];
                    Guid producerId = producerIds[i % numProducers];
                    var grain = GrainClient.GrainFactory.GetGrain<IStreamLifecycleProducerGrain>(producerId);

                    Task promise = grain.BecomeProducer(streamId, this.StreamNamespace, streamProviderName);

                    promises.Add(promise);
                    pipeline.Add(promise);
                }
                pipeline.Wait();
                promises.Clear();
            }

            // Consumers
            for (int i = 0; i < numStreams; i++)
            {
                Guid streamId = streamIds[i];

                Task promise = SetupOneStream(streamId, streamProviderName, pipeline, numConsumers, 0, normalSubscribeCalls);
                promises.Add(promise);
            }
            pipeline.Wait();

            Task.WhenAll(promises).Wait();
            sw.Stop();

            int consumerCount = ActiveGrainCount(typeof(StreamLifecycleConsumerGrain).FullName);
            Assert.AreEqual(activeConsumerGrains + (numStreams * numConsumers), consumerCount, "The right number of Consumer grains are active");

            int producerCount = ActiveGrainCount(typeof(StreamLifecycleProducerGrain).FullName);
            Assert.AreEqual(activeProducerGrains + (numStreams * numProducers), producerCount, "The right number of Producer grains are active");

            int pubSubCount = ActiveGrainCount(typeof(PubSubRendezvousGrain).FullName);
            Assert.AreEqual(streamIds.Length, pubSubCount, "Final PubSub count -- no more started");

            TimeSpan elapsed = sw.Elapsed;
            int totalSubscriptions = numStreams * numConsumers;
            double rps = totalSubscriptions / elapsed.TotalSeconds;
            Console.WriteLine("Subscriptions-per-second = {0} during period {1}", rps, elapsed);
            Assert.AreNotEqual(0.0, rps, "RPS greater than zero");
            return TaskDone.Done;
        }
예제 #16
0
        private async Task AsyncPipelineBlackBoxConsistencyTest(int workerCount)
        {
            if (workerCount < 1)
            {
                throw new ArgumentOutOfRangeException("You must specify at least one worker.", "workerCount");
            }

            int          loopCount = _iterationCount / workerCount;
            const double variance  = 0.1;
            int          expectedTasksCompleted = loopCount * workerCount;
            var          delayLength            = TimeSpan.FromSeconds(1);
            const int    pipelineCapacity       = _defaultPipelineCapacity;
            var          pipeline       = new AsyncPipeline(pipelineCapacity);
            int          tasksCompleted = 0;

            // the following value is wrapped within an array to avoid a modified closure warning from ReSharper.
            int[] pipelineSize    = { 0 };
            var   capacityReached = new InterlockedFlag();

            Action workFunc =
                () =>
            {
                var sz = Interlocked.Increment(ref pipelineSize[0]);
                CheckPipelineState(sz, pipelineCapacity, capacityReached);
                Task.Delay(delayLength).Wait();
                Interlocked.Decrement(ref pipelineSize[0]);
                Interlocked.Increment(ref tasksCompleted);
            };

            Action workerFunc =
                () =>
            {
                for (var j = 0; j < loopCount; j++)
                {
                    Task task = new Task(workFunc);
                    pipeline.Add(task, whiteBox: null);
                    task.Start();
                }
            };

            Func <Task> monitorFunc =
                async() =>
            {
                var delay = TimeSpan.FromSeconds(5);
                while (tasksCompleted < expectedTasksCompleted)
                {
                    Console.WriteLine("test in progress: tasksCompleted = {0}.", tasksCompleted);
                    await Task.Delay(delay);
                }
            };

            var workers   = new Task[workerCount];
            var stopwatch = Stopwatch.StartNew();

            for (var i = 0; i < workerCount; ++i)
            {
                workers[i] = Task.Run(workerFunc);
            }
            Task.Run(monitorFunc).Ignore();
            await Task.WhenAll(workers);

            pipeline.Wait();
            stopwatch.Stop();
            Assert.AreEqual(expectedTasksCompleted, tasksCompleted, "The test did not complete the expected number of tasks.");

            var targetTimeSec = expectedTasksCompleted * delayLength.TotalSeconds / pipelineCapacity;
            var minTimeSec    = (1.0 - variance) * targetTimeSec;
            var maxTimeSec    = (1.0 + variance) * targetTimeSec;
            var actualSec     = stopwatch.Elapsed.TotalSeconds;

            Console.WriteLine(
                "Test finished in {0} sec, {1}% of target time {2} sec. Permitted variance is +/-{3}%",
                actualSec,
                actualSec / targetTimeSec * 100,
                targetTimeSec,
                variance * 100);

            Assert.IsTrue(capacityReached.IsSet, "Pipeline capacity not reached; the delay length probably is too short to be useful.");
            Assert.IsTrue(
                actualSec >= minTimeSec,
                string.Format("The unit test completed too early ({0} sec < {1} sec).", actualSec, minTimeSec));
            Assert.IsTrue(
                actualSec <= maxTimeSec,
                string.Format("The unit test completed too late ({0} sec > {1} sec).", actualSec, maxTimeSec));
        }
예제 #17
0
        private async Task InitializeTopology(Guid streamId, string streamNamespace, string streamProviderName,
                                              int numProducers, int numConsumers,
                                              List <IStreamLifecycleProducerGrain> producers, List <IStreamLifecycleConsumerGrain> consumers,
                                              bool useFanOut)
        {
            long nextGrainId = random.Next();

            //var promises = new List<Task>();
            AsyncPipeline pipeline = new AsyncPipeline(InitPipelineSize);

            // Consumers
            long consumerIdStart = nextGrainId;

            for (int loopCount = 0; loopCount < numConsumers; loopCount++)
            {
                var grain = this.GrainFactory.GetGrain <IStreamLifecycleConsumerGrain>(Guid.NewGuid());
                consumers.Add(grain);

                Task promise = grain.BecomeConsumer(streamId, streamNamespace, streamProviderName);

                if (useFanOut)
                {
                    pipeline.Add(promise);
                    //promises.Add(promise);

                    //if (loopCount%WaitBatchSize == 0)
                    //{
                    //    output.WriteLine("InitializeTopology: Waiting for {0} consumers to initialize", promises.Count);
                    //    await Task.WhenAll(promises);
                    //    promises.Clear();
                    //}
                }
                else
                {
                    await promise;
                }
            }
            if (useFanOut)
            {
                //output.WriteLine("InitializeTopology: Waiting for {0} consumers to initialize", promises.Count);
                //await Task.WhenAll(promises);
                //promises.Clear();
                //output.WriteLine("InitializeTopology: Waiting for {0} consumers to initialize", pipeline.Count);
                pipeline.Wait();
            }
            nextGrainId += numConsumers;

            // Producers
            long producerIdStart = nextGrainId;

            pipeline = new AsyncPipeline(InitPipelineSize);
            for (int loopCount = 0; loopCount < numProducers; loopCount++)
            {
                var grain = this.GrainFactory.GetGrain <IStreamLifecycleProducerGrain>(Guid.NewGuid());
                producers.Add(grain);

                Task promise = grain.BecomeProducer(streamId, streamNamespace, streamProviderName);

                if (useFanOut)
                {
                    pipeline.Add(promise);
                    //promises.Add(promise);
                }
                else
                {
                    await promise;
                }
            }
            if (useFanOut)
            {
                //output.WriteLine("InitializeTopology: Waiting for {0} producers to initialize", promises.Count);
                //await Task.WhenAll(promises);
                //promises.Clear();
                //output.WriteLine("InitializeTopology: Waiting for {0} producers to initialize", pipeline.Count);
                pipeline.Wait();
            }
            //nextGrainId += numProducers;
        }
예제 #18
0
        //private async Task Test_Stream_Churn_TimePeriod(
        //    string streamProviderName,
        //    int pipelineSize,
        //    TimeSpan duration,
        //    int numConsumers = 9,
        //    int numProducers = 1)
        //{
        //    Console.WriteLine("Testing Subscription churn for duration {0} with {1} Consumers and {2} Producers per Stream",
        //        duration, numConsumers, numProducers);

        //    AsyncPipeline pipeline = new AsyncPipeline(pipelineSize);
        //    var promises = new List<Task>();

        //    Stopwatch sw = Stopwatch.StartNew();

        //    for (int i = 0; sw.Elapsed <= duration; i++)
        //    {
        //        Guid streamId = Guid.NewGuid();
        //        Task promise = SetupOneStream(streamId, streamProviderName, pipeline, numConsumers, numProducers);
        //        promises.Add(promise);
        //    }
        //    await Task.WhenAll(promises);
        //    sw.Stop();
        //    TimeSpan elapsed = sw.Elapsed;
        //    int totalSubscription = numSt* numConsumers);
        //    double rps = totalSubscription/elapsed.TotalSeconds;
        //    Console.WriteLine("Subscriptions-per-second = {0} during period {1}", rps, elapsed);
        //    Assert.AreNotEqual(0.0, rps, "RPS greater than zero");
        //}

        private void WarmUpPubSub(string streamProviderName, Guid[] streamIds, AsyncPipeline pipeline)
        {
            int numStreams = streamIds.Length;
            // Warm up PubSub for the appropriate streams
            for (int i = 0; i < numStreams; i++)
            {
                Guid streamId = streamIds[i];
                string extKey = streamProviderName + "_" + StreamNamespace;

                IPubSubRendezvousGrain pubsub = GrainClient.GrainFactory.GetGrain<IPubSubRendezvousGrain>(streamId, extKey, null);

                Task promise = pubsub.Validate();

                pipeline.Add(promise);
            }
            pipeline.Wait();
        }