public void When_multiple_properties_are_registered_under_the_same_name_it_should_only_remember_the_last_one()
        {
            DateTime nowUtc = 16.June(2017).At(15, 00).AsUtc();

            var stats = new ProjectionStats(() => nowUtc);

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
            stats.StoreProperty("myProjector", "theName", "aValue");

            nowUtc = nowUtc.Add(1.Hours());

            stats.StoreProperty("myProjector", "theName", "anotherValue");

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------
            var projectorStats = stats.Should().ContainSingle(s => s.ProjectorId == "myProjector").Subject;

            projectorStats.GetProperties().Should().ContainKey("theName");
            projectorStats.GetProperties()["theName"].Should().BeEquivalentTo(new
            {
                Value        = "anotherValue",
                TimestampUtc = nowUtc
            });
        }
Example #2
0
            public When_a_specific_projector_is_requested()
            {
                Given(() =>
                {
                    var nowUtc = 10.July(2017).At(10, 39).AsUtc();
                    var stats  = new ProjectionStats(() => nowUtc);

                    stats.TrackProgress("id1", 1000);
                    stats.StoreProperty("id1", "property1", "value1");

                    var appBuilder = new AppBuilder();
                    appBuilder.UseLiquidProjections(stats);

                    var httpClient = new HttpClient(new OwinHttpMessageHandler(appBuilder.Build()));
                    httpClient.DefaultRequestHeaders.Accept.Add(
                        new MediaTypeWithQualityHeaderValue("application/json"));

                    WithSubject(ct => httpClient);
                });

                When(async() =>
                {
                    return(await Subject.GetAsync("http://localhost/projectionStats/id1"));
                });
            }
        public void When_the_projector_runs_at_a_very_low_speed_it_should_still_calculate_the_eta()
        {
            //-----------------------------------------------------------------------------------------------------------
            // Arrange
            //-----------------------------------------------------------------------------------------------------------
            DateTime nowUtc = 16.June(2017).At(15, 00).AsUtc();

            var stats = new ProjectionStats(() => nowUtc);

            long transactionsPer5Seconds = 1;

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
            long checkpoint = 0;

            for (int seconds = 0; seconds < 60; seconds += 5)
            {
                checkpoint += transactionsPer5Seconds;

                stats.TrackProgress("myProjector", checkpoint);

                nowUtc = nowUtc.Add(5.Seconds());
            }

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------

            TimeSpan?eta = stats.GetTimeToReach("myProjector", 100000);

            long secondsToComplete = ((100000 - checkpoint) / transactionsPer5Seconds * 5);

            eta.Should().BeCloseTo(TimeSpan.FromSeconds(secondsToComplete), 1000);
        }
        public void When_checking_in_multiple_times_for_a_projector_it_should_remember_the_last_only()
        {
            //-----------------------------------------------------------------------------------------------------------
            // Arrange
            //-----------------------------------------------------------------------------------------------------------
            DateTime nowUtc = 16.June(2017).At(15, 00).AsUtc();

            var stats = new ProjectionStats(() => nowUtc);

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
            stats.TrackProgress("myProjector", 1000);

            nowUtc = nowUtc.Add(1.Hours());

            stats.TrackProgress("myProjector", 2000);

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------
            var projectorStats = stats.Should().ContainSingle(s => s.ProjectorId == "myProjector").Subject;

            projectorStats.LastCheckpoint.Checkpoint.Should().Be(2000);
            projectorStats.LastCheckpoint.TimestampUtc.Should().Be(nowUtc);
        }
        public static void Main(string[] args)
        {
            var container = TinyIoCContainer.Current;

            var eventStore = new JsonFileEventStore("ExampleEvents.zip", 100);

            var projectionsStore = new InMemoryDatabase();

            container.Register(projectionsStore);

            var dispatcher = new Dispatcher(eventStore.Subscribe);

            var stats = new ProjectionStats(() => DateTime.UtcNow);

            var bootstrapper = new CountsProjector(dispatcher, projectionsStore, stats);

            var startOptions = new StartOptions($"http://localhost:9000");

            using (WebApp.Start(startOptions, builder =>
            {
                builder.UseControllers(container);
                builder.UseLiquidProjections(stats);
            }))
            {
                bootstrapper.Start();

                Console.WriteLine($"HTTP endpoint available at http://localhost:9000/api/Statistics/CountsPerState");

                Console.ReadLine();
            }
        }
Example #6
0
        public CountsProjector(Dispatcher dispatcher, InMemoryDatabase store, ProjectionStats stats)
        {
            this.dispatcher = dispatcher;
            this.store      = store;
            this.stats      = stats;

            BuildCountryProjector();
            BuildDocumentProjector();
        }
        public ExampleProjector(IEventMapBuilder <TProjection, string, ProjectionContext> mapBuilder, InMemoryDatabase store,
                                ProjectionStats stats, params IExampleProjector[] childProjectors)
        {
            this.store = store;
            this.stats = stats;
            var map = BuildMapFrom(mapBuilder);

            InnerProjector = new Projector(map, childProjectors.Select(p => p.InnerProjector));
        }
        public void When_the_projector_runs_for_more_than_10_minutes_it_should_only_evaluate_the_last_10_minutes()
        {
            //-----------------------------------------------------------------------------------------------------------
            // Arrange
            //-----------------------------------------------------------------------------------------------------------
            DateTime nowUtc = 16.June(2017).At(15, 00).AsUtc();

            var stats = new ProjectionStats(() => nowUtc);

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
            long checkpoint = 0;

            // The first ten minutes should be ignored
            for (int seconds = 0; seconds < (10 * 60); ++seconds)
            {
                checkpoint += 1000;

                stats.TrackProgress("myProjector", checkpoint);

                nowUtc = nowUtc.Add(1.Seconds());
            }

            // Then nine minutes of 2000/s.
            for (int seconds = 0; seconds < (9 * 60); ++seconds)
            {
                checkpoint += 2000;

                stats.TrackProgress("myProjector", checkpoint);

                nowUtc = nowUtc.Add(1.Seconds());
            }

            // The last minute should run on 3000/s
            for (int seconds = 0; seconds < (60); ++seconds)
            {
                checkpoint += 3000;

                stats.TrackProgress("myProjector", checkpoint);

                nowUtc = nowUtc.Add(1.Seconds());
            }

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------
            TimeSpan?eta = stats.GetTimeToReach("myProjector", checkpoint + 100000);

            float precalculatedWeightedAveragePerSecond = 2222.5022F;

            long secondsToComplete = (long)(100000 / precalculatedWeightedAveragePerSecond);

            eta.Should().Be(TimeSpan.FromSeconds(secondsToComplete));
            stats.GetSpeed("myProjector").Should().BeApproximately(precalculatedWeightedAveragePerSecond, 1);
        }
Example #9
0
        public void ConfigureServices(IServiceCollection services)
        {
            var eventStore       = new JsonFileEventStore("ExampleEvents.zip", 100);
            var projectionsStore = new InMemoryDatabase();

            var dispatcher   = new Dispatcher(eventStore.Subscribe);
            var stats        = new ProjectionStats(() => System.DateTime.UtcNow);
            var bootstrapper = new CountsProjector(dispatcher, projectionsStore, stats);

            services
            .AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddSingleton <InMemoryDatabase>(projectionsStore);
            services.AddSingleton <ProjectionStats>(stats);

            bootstrapper.Start();
        }
        public void When_the_projector_has_not_checked_in_yet_it_should_not_provide_an_eta()
        {
            //-----------------------------------------------------------------------------------------------------------
            // Arrange
            //-----------------------------------------------------------------------------------------------------------
            var stats = new ProjectionStats(() => DateTime.UtcNow);

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
            TimeSpan?eta = stats.GetTimeToReach("myProjector", 100000);

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------
            eta.Should().NotHaveValue();

            stats.GetSpeed("myProjector").Should().BeNull();
        }
        public void When_the_projectors_speed_increases_it_should_favor_the_higher_speed_in_the_eta()
        {
            //-----------------------------------------------------------------------------------------------------------
            // Arrange
            //-----------------------------------------------------------------------------------------------------------
            DateTime nowUtc = 16.June(2017).At(15, 00).AsUtc();

            var stats = new ProjectionStats(() => nowUtc);

            long transactionsPerSecond = 1000;

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
            long checkpoint = 0;

            for (int seconds = 0; seconds < 60; ++seconds)
            {
                checkpoint += transactionsPerSecond;

                stats.TrackProgress("myProjector", checkpoint);

                nowUtc = nowUtc.Add(1.Seconds());
                transactionsPerSecond += 100;
            }

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------
            TimeSpan?eta = stats.GetTimeToReach("myProjector", checkpoint + 100000);

            long weightedAveragePerSecond = 4550;

            stats.GetSpeed("myProjector").Should().Be(weightedAveragePerSecond);


            long secondsToComplete = 100000 / weightedAveragePerSecond;

            eta.Should().Be(TimeSpan.FromSeconds(secondsToComplete));
        }
        public void When_the_projector_is_ahead_of_the_requested_checkpoint_the_eta_should_be_zero()
        {
            //-----------------------------------------------------------------------------------------------------------
            // Arrange
            //-----------------------------------------------------------------------------------------------------------
            DateTime utcNow = new DateTime(2017, 7, 4, 11, 50, 0, DateTimeKind.Utc);
            var      stats  = new ProjectionStats(() => utcNow);

            stats.TrackProgress("myProjector", 1000);

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
            utcNow = new DateTime(2017, 7, 4, 11, 52, 0, DateTimeKind.Utc);
            stats.TrackProgress("myProjector", 10000);

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------
            stats.GetSpeed("myProjector").Should().Be((10000 - 1000) / 120);
            stats.GetTimeToReach("myProjector", 5000).Should().Be(TimeSpan.Zero);
        }
        public void When_the_projector_runs_at_a_constant_speed_it_should_use_that_to_calculate_the_eta()
        {
            //-----------------------------------------------------------------------------------------------------------
            // Arrange
            //-----------------------------------------------------------------------------------------------------------
            DateTime nowUtc = 16.June(2017).At(15, 00).AsUtc();

            var stats = new ProjectionStats(() => nowUtc);

            long transactionsPerSecond = 1000;

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
            long checkpoint = 0;

            for (int seconds = 0; seconds < 60; ++seconds)
            {
                checkpoint += transactionsPerSecond;

                stats.TrackProgress("myProjector", checkpoint);

                nowUtc = nowUtc.Add(1.Seconds());
            }

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------
            TimeSpan?eta = stats.GetTimeToReach("myProjector", 100000);

            stats.GetSpeed("myProjector").Should().Be(transactionsPerSecond);

            long secondsToComplete = (100000 - checkpoint) / transactionsPerSecond;

            eta.Should().Be(TimeSpan.FromSeconds(secondsToComplete));
        }
        public void When_multiple_events_are_registered_it_should_remember_their_timestamps()
        {
            //-----------------------------------------------------------------------------------------------------------
            // Arrange
            //-----------------------------------------------------------------------------------------------------------
            DateTime nowUtc = 16.June(2017).At(15, 00).AsUtc();

            var stats = new ProjectionStats(() => nowUtc);

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
            stats.LogEvent("myProjector", "first event");

            nowUtc = nowUtc.At(16, 00).AsUtc();
            stats.LogEvent("myProjector", "second event");

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------
            var projectorStats = stats.Should().ContainSingle(s => s.ProjectorId == "myProjector").Subject;

            projectorStats.GetEvents().Should().BeEquivalentTo(new[]
            {
                new
                {
                    Body         = "first event",
                    TimestampUtc = nowUtc.At(15, 00)
                },
                new
                {
                    Body         = "second event",
                    TimestampUtc = nowUtc.At(16, 00)
                }
            });
        }
Example #15
0
 public ProjectionStatsController(ProjectionStats projectionStats)
 {
     _projectionStats = projectionStats;
 }