Ejemplo n.º 1
0
        public void Concurrent_read_only_access_to_aggregate_history_can_occur_in_paralell()
        {
            var user = new User();

            user.Register("*****@*****.**", "password", Guid.NewGuid());
            using (var session = OpenSession(CreateStore()))
            {
                session.Save(user);
            }

            var iterations = 20;
            var delayEachTransactionByMilliseconds = 100;

            Action readUserHistory = () =>
            {
                using (var session = OpenSession(CreateStore()))
                {
                    using (var transaction = new TransactionScope())
                    {
                        ((IEventStoreReader)session).GetHistory(user.Id);
                        Thread.Sleep(TimeSpanExtensions.Milliseconds(delayEachTransactionByMilliseconds));
                        transaction.Complete();
                    }
                }
            };

            readUserHistory();//one warmup to get consistent times later.
            var timeForSingleTransactionalRead = (int)StopwatchExtensions.TimeExecution(readUserHistory).TotalMilliseconds;

            var timingsSummary = TimeAsserter.ExecuteThreaded(
                readUserHistory,
                iterations: iterations,
                timeIndividualExecutions: true,
                maxTotal: ((iterations * timeForSingleTransactionalRead) / 2).Milliseconds(),
                description: $"If access is serialized the time will be approximately {iterations * timeForSingleTransactionalRead} milliseconds. If parelellized it should be far below this value.");

            timingsSummary.Average.Should().BeLessThan(delayEachTransactionByMilliseconds.Milliseconds());

            timingsSummary.IndividualExecutionTimes.Sum().Should().BeGreaterThan(timingsSummary.Total);
        }