Esempio n. 1
0
        private async Task ReplayEvents(ILoggerFactory loggerFactory, DenormalizerDispatcher dispatcher,
                                        AzureTableStorageOptions dboptions)
        {
            var logger = loggerFactory.CreateLogger("Replay");

            logger.LogInformation("Replaying all the events from event store to denormalizers.");

            var tc    = new TelemetryClient();
            var watch = Stopwatch.StartNew();


            var eventStore = new EventStream(dboptions);

            var allEvents = await eventStore.ReadAllEvents();

            watch.Stop();
            tc.TrackMetric("LoadEvents", watch.ElapsedMilliseconds);
            Trace.TraceInformation("Events queried from event store in {0:n0} ms.", watch.ElapsedMilliseconds);

            watch = Stopwatch.StartNew();

            var i = 0;

            foreach (var e in allEvents)
            {
                dispatcher.ReplayEvent(e);
                i++;
            }

            watch.Stop();
            logger.LogInformation("Replay complete in {0:n0} ms. Replayed {1} events.", watch.ElapsedMilliseconds, i);
            tc.TrackMetric("ReplayEvents", watch.ElapsedMilliseconds);
            tc.TrackMetric("ReplayEventsCount", i);
        }
Esempio n. 2
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        // Since this method is resolved through the DI already, we can request any registered services by
        // just adding respective parameters.
        public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env,
            ILoggerFactory loggerFactory,
            IEventTopic eventTopic,
            DenormalizerDispatcher dispatcher,
            CommandHandlerFactory commandHandlerFactory,
            IOptions <AzureTableStorageOptions> tableStorageOptions,
            IHubContext <CommandBus> commandBus)
        {
            Startup.CommandBus = commandBus;

            var configureLogger = loggerFactory.CreateLogger("Configure");

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseRewriter(new RewriteOptions().AddRedirectToHttps());
            }

            app.UseStaticFiles();
            app.UseAuthentication();

            // Replay all events once from DB to the in-memory query model.
            // Explicitly wait as routing (below) and controllers expect the state is loaded .
            ReplayEvents(loggerFactory, dispatcher, tableStorageOptions.Value).Wait();

            // Register all denormalizers to listen for all events. Could have more fine grained subscription logic, but this works for now.
            foreach (var d in dispatcher.Denormalizers.Cast <IEventConsumer>())
            {
                configureLogger.LogInformation("Registering denormalizer {0} to receive all events", d.GetType());
                eventTopic.Subscribe(d);
            }

            // Register all command handlers to listen for all events.
            foreach (var d in commandHandlerFactory.All.Cast <IEventConsumer>())
            {
                configureLogger.LogInformation("Registering command handler {0} to receive all events", d.GetType());
                eventTopic.Subscribe(d);
            }

            // Routes use event data (state after events), therefore register routes only after the replay
            string defaultHappening = QueryModelRepository.Routing.DefaultHappening;

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "root",
                    template: "{happening:regex(^satku[a-z]+$)?}",
                    defaults: new { happening = defaultHappening, Controller = "Home", Action = "Index" },
                    constraints: null,
                    dataTokens: new { DefaultHappening = defaultHappening });

                routes.MapRoute(
                    name: "default",
                    template: "{happening:regex(^satku[a-z]+$)}/{*catchall}",
                    defaults: new { happening = defaultHappening, Controller = "Home", Action = "Index" },
                    constraints: null,
                    dataTokens: new { DefaultHappening = defaultHappening });
            });

            app.UseSignalR(routes =>
            {
                routes.MapHub <CommandBus>("commandbus");
            });
        }