public void Projection_write_speed_without_unit_of_work() { var eventsRead = 0; var projector1 = Projector.Create <IEvent>(e => { using (var db = new ReadModelDbContext()) { db.Set <ProductInventory>().Add(new ProductInventory { ProductName = Guid.NewGuid().ToString(), QuantityInStock = Any.Int(1, 5), QuantityReserved = 0 }); db.SaveChanges(); eventsRead++; } }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); using (var catchup = new ReadModelCatchup(projector1) { StartAtEventId = startAtEventId }) { catchup.Run(); } Console.WriteLine(new { eventsRead }); // TODO: (Write_speed_without_unit_of_work) write test Assert.Fail("Test not written yet."); }
public void Projection_write_speed_with_unit_of_work() { var eventsRead = 0; var projector1 = Projector.Create <IEvent>(e => { using (var update = this.Update()) { var db = update.Resource <ReadModelDbContext>(); db.Set <ProductInventory>().Add(new ProductInventory { ProductName = Guid.NewGuid().ToString(), QuantityInStock = Any.Int(1, 5), QuantityReserved = 0 }); db.SaveChanges(); eventsRead++; } }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); using (var catchup = new ReadModelCatchup( eventStoreDbContext: () => EventStoreDbContext(), readModelDbContext: () => ReadModelDbContext(), startAtEventId: startAtEventId, projectors: projector1)) { catchup.Run(); } Console.WriteLine(new { eventsRead }); }
public ReadModelCatchup CreateReadModelCatchup( Expression <Func <StorableEvent, bool> > filter = null, int batchSize = 10000, long?startAtEventId = null, params object[] projectors) { startAtEventId = startAtEventId ?? HighestEventId + 1; var catchupName = CatchupName(projectors, startAtEventId); var catchup = new ReadModelCatchup( eventStoreDbContext: () => EventStoreDbContext(), readModelDbContext: () => ReadModelDbContext(), startAtEventId: startAtEventId.Value, projectors: projectors, batchSize: batchSize, filter: filter) { Name = catchupName }; Configuration.Current.RegisterForDisposal(catchup); return(catchup); }
/// <summary> /// Configures the system to use SQL-backed command scheduling. /// </summary> /// <param name="configuration">The configuration.</param> /// <returns>The updated configuration.</returns> public static Configuration UseSqlCommandScheduling( this Configuration configuration, Action<ReadModelCatchup<CommandSchedulerDbContext>> configureCatchup = null) { var container = configuration.Container; var scheduler = container.Resolve<SqlCommandScheduler>(); var subscription = container.Resolve<IEventBus>().Subscribe(scheduler); configuration.RegisterForDisposal(subscription); container.RegisterSingle(c => scheduler); if (configureCatchup != null) { var catchup = new ReadModelCatchup<CommandSchedulerDbContext>(scheduler) { CreateReadModelDbContext = scheduler.CreateCommandSchedulerDbContext }; configureCatchup(catchup); catchup.PollEventStore(); container.RegisterSingle(c => catchup); configuration.RegisterForDisposal(catchup); } configuration.UsesSqlCommandScheduling(true); return configuration; }
public virtual CatchupWrapper CreateReadModelCatchup(params object[] projectors) { var startAtEventId = HighestEventId + 1; var catchup = new ReadModelCatchup(projectors) { StartAtEventId = startAtEventId, Name = "from " + startAtEventId }; disposables.Add(catchup); return(new CatchupWrapper <ReadModelDbContext>(catchup)); }
public void Read_speed_for_IEvent() { var eventsRead = 0; var projector1 = Projector.Create<IEvent>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); using (var catchup = new ReadModelCatchup(projector1) { StartAtEventId = startAtEventId }) { catchup.Run(); } Console.WriteLine(new { eventsRead }); }
public ReadModelCatchup CreateReadModelCatchup(params object[] projectors) { var catchup = new ReadModelCatchup( eventStoreDbContext: () => EventStoreDbContext(), readModelDbContext: () => ReadModelDbContext(), startAtEventId: HighestEventId + 1, projectors: projectors) { Name = $"from {HighestEventId + 1}" }; Configuration.Current.RegisterForDisposal(catchup); return(catchup); }
public void Read_speed_for_two_specific_events() { var eventsRead = 0; var projector1 = Projector.Create<Order.ItemAdded>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); var projector2 = Projector.Create<CustomerAccount.RequestedNoSpam>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector2"); using (var catchup = new ReadModelCatchup(projector1, projector2) { StartAtEventId = startAtEventId }) { catchup.Run(); } Console.WriteLine(new { eventsRead }); }
public ReadModelCatchup CreateReadModelCatchup(params object[] projectors) { var catchup = new ReadModelCatchup( eventStoreDbContext: () => EventStoreDbContext(), readModelDbContext: () => ReadModelDbContext(), startAtEventId: HighestEventId + 1, projectors: projectors) { Name = "from " + (HighestEventId + 1) }; disposables.Add(catchup); return(catchup); }
public void Read_speed_for_IEvent() { var eventsRead = 0; var projector1 = Projector.Create<IEvent>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); using (var catchup = new ReadModelCatchup( eventStoreDbContext: () => EventStoreDbContext(), readModelDbContext: () => ReadModelDbContext(), startAtEventId: startAtEventId, projectors: projector1)) { catchup.Run(); } Console.WriteLine(new { eventsRead }); }
public void Read_speed_for_IEvent() { var eventsRead = 0; var projector1 = Projector.Create <IEvent>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); using (var catchup = new ReadModelCatchup(projector1) { StartAtEventId = startAtEventId }) { catchup.Run(); } Console.WriteLine(new { eventsRead }); }
public void Read_speed_for_IEvent() { var eventsRead = 0; var projector1 = Projector.Create <IEvent>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); using (var catchup = new ReadModelCatchup( eventStoreDbContext: () => EventStoreDbContext(), readModelDbContext: () => ReadModelDbContext(), startAtEventId: startAtEventId, projectors: projector1)) { catchup.Run(); } Console.WriteLine(new { eventsRead }); }
public ReadModelCatchup CreateReadModelCatchup( object[] projectors, Func <EventStoreDbContext> eventStoreDbContext, Func <ReadModelDbContext> readModelDbContext = null) { var catchup = new ReadModelCatchup( eventStoreDbContext: eventStoreDbContext, readModelDbContext: readModelDbContext ?? (() => ReadModelDbContext()), startAtEventId: HighestEventId + 1, projectors: projectors) { Name = $"from {HighestEventId + 1}" }; Configuration.Current.RegisterForDisposal(catchup); return(catchup); }
public void Read_speed_for_two_specific_events() { var eventsRead = 0; var projector1 = Projector.Create <Order.ItemAdded>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); var projector2 = Projector.Create <CustomerAccount.RequestedNoSpam>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector2"); using (var catchup = new ReadModelCatchup(projector1, projector2) { StartAtEventId = startAtEventId }) { catchup.Run(); } Console.WriteLine(new { eventsRead }); }
public ReadModelCatchup <T> CreateReadModelCatchup <T>( Func <EventStoreDbContext> eventStoreDbContext, params object[] projectors) where T : DbContext, new() { var catchup = new ReadModelCatchup <T>( eventStoreDbContext: eventStoreDbContext, readModelDbContext: () => new T(), startAtEventId: HighestEventId + 1, projectors: projectors) { Name = "from " + (HighestEventId + 1) }; disposables.Add(catchup); return(catchup); }
public ReadModelCatchup <T> CreateReadModelCatchup <T>( Func <EventStoreDbContext> eventStoreDbContext, params object[] projectors) where T : DbContext, new() { var catchup = new ReadModelCatchup <T>( eventStoreDbContext: eventStoreDbContext, readModelDbContext: () => new T(), startAtEventId: HighestEventId + 1, projectors: projectors) { Name = $"from {HighestEventId + 1}" }; Configuration.Current.RegisterForDisposal(catchup); return(catchup); }
public void Read_speed_for_two_specific_events() { var eventsRead = 0; var projector1 = Projector.Create <Order.ItemAdded>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); var projector2 = Projector.Create <CustomerAccount.RequestedNoSpam>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector2"); using (var catchup = new ReadModelCatchup( eventStoreDbContext: () => EventStoreDbContext(), readModelDbContext: () => ReadModelDbContext(), startAtEventId: startAtEventId, projectors: new object[] { projector1, projector2 })) { catchup.Run(); } Console.WriteLine(new { eventsRead }); }
public void ReadModelCatchup_StartAtEventId_can_be_used_to_avoid_requery_of_previous_events() { var lastEventId = Events.Write(50, _ => Events.Any()); var eventsProjected = 0; var projector = Projector.Create <Event>(e => { eventsProjected++; }).Named(MethodBase.GetCurrentMethod().Name); using (var catchup = new ReadModelCatchup(projector) { StartAtEventId = lastEventId - 20 }) { catchup.Run(); } eventsProjected.Should().Be(21); }
public async Task ReadModelCatchup_StartAtEventId_can_be_used_to_avoid_requery_of_previous_events() { var lastEventId = Events.Write(50, _ => Events.Any()); var eventsProjected = 0; var projector = Projector.Create <Event>(e => { eventsProjected++; }) .Named(MethodBase.GetCurrentMethod().Name); using (var catchup = new ReadModelCatchup( eventStoreDbContext: () => EventStoreDbContext(), readModelDbContext: () => ReadModelDbContext(), startAtEventId: lastEventId - 20, projectors: projector)) { await catchup.Run(); } eventsProjected.Should().Be(21); }
/// <summary> /// Configures the system to use SQL-backed command scheduling. /// </summary> /// <param name="configuration">The configuration.</param> /// <returns>The updated configuration.</returns> public static Configuration UseSqlCommandScheduling( this Configuration configuration, Action<ReadModelCatchup<CommandSchedulerDbContext>> configureCatchup = null) { var container = configuration.Container; container.AddFallbackToDefaultClock(); var scheduler = new SqlCommandScheduler( configuration, container.Resolve<Func<CommandSchedulerDbContext>>(), container.Resolve<GetClockName>()); if (container.All(r => r.Key != typeof (SqlCommandScheduler))) { container.Register(c => scheduler) .Register<ISchedulerClockTrigger>(c => scheduler) .Register<ISchedulerClockRepository>(c => scheduler); } var subscription = container.Resolve<IEventBus>().Subscribe(scheduler); configuration.RegisterForDisposal(subscription); container.RegisterSingle(c => scheduler); if (configureCatchup != null) { var catchup = new ReadModelCatchup<CommandSchedulerDbContext>(scheduler) { CreateReadModelDbContext = scheduler.CreateCommandSchedulerDbContext }; configureCatchup(catchup); catchup.PollEventStore(); container.RegisterSingle(c => catchup); configuration.RegisterForDisposal(catchup); } configuration.IsUsingSqlCommandScheduling(true); return configuration; }
private void RunCatchup() { // TODO: (RunCatchup) provide trace output here and throughout var projectors = handlers.OrEmpty() .Where(h => h.GetType().IsProjectorType()) .ToArray(); if (!projectors.Any()) { return; } if (configuration.IsUsingSqlEventStore()) { var catchup = new ReadModelCatchup(projectors) { CreateEventStoreDbContext = CreateEventStoreDbContext, CreateReadModelDbContext = CreateReadModelDbContext, StartAtEventId = startCatchupAtEventId }; using (catchup) using (catchup.EventBus.Errors.Subscribe(scenario.AddEventHandlingError)) using (catchup.Progress.Subscribe(s => Console.WriteLine(s))) { catchup.Run(); } } else { EventBus.PublishAsync(InitialEvents.ToArray()).Wait(); } if (scenario.EventHandlingErrors.Any()) { throw new ScenarioSetupException( "The following event handling errors occurred during projection catchup: " + string.Join("\n", scenario.EventHandlingErrors.Select(e => e.Exception.ToString()))); } }
public async Task Two_different_projectors_can_catch_up_to_two_different_event_stores_using_separate_catchups() { // arrange var projector1CallCount = 0; var projector2CallCount = 0; var projector1 = Projector.Create <Order.ItemAdded>(e => projector1CallCount++).Named(MethodBase.GetCurrentMethod().Name + "1"); var projector2 = Projector.Create <Order.ItemAdded>(e => projector2CallCount++).Named(MethodBase.GetCurrentMethod().Name + "2"); var startProjector2AtId = new OtherEventStoreDbContext().DisposeAfter(db => db.HighestEventId()) + 1; Events.Write(5, createEventStore: () => EventStoreDbContext()); Events.Write(5, createEventStore: () => new OtherEventStoreDbContext()); using (var eventStoreCatchup = new ReadModelCatchup( readModelDbContext: () => ReadModelDbContext(), eventStoreDbContext: () => EventStoreDbContext(), startAtEventId: HighestEventId + 1, projectors: projector1) { Name = "eventStoreCatchup" }) using (var otherEventStoreCatchup = new ReadModelCatchup( readModelDbContext: () => ReadModelDbContext(), eventStoreDbContext: () => new OtherEventStoreDbContext(), startAtEventId: startProjector2AtId, projectors: projector2) { Name = "otherEventStoreCatchup" }) { // act await eventStoreCatchup.SingleBatchAsync(); await otherEventStoreCatchup.SingleBatchAsync(); } // assert projector1CallCount.Should().Be(5, "projector1 should get all events from event stream"); projector2CallCount.Should().Be(5, "projector2 should get all events from event stream"); }
private void RunCatchup() { var projectors = handlers.OrEmpty() .Where(h => h.GetType().IsProjectorType()) .ToArray(); if (!projectors.Any()) { return; } if (configuration.IsUsingSqlEventStore()) { var catchup = new ReadModelCatchup( eventStoreDbContext: () => configuration.EventStoreDbContext(), readModelDbContext: () => configuration.ReadModelDbContext(), startAtEventId: startCatchupAtEventId, projectors: projectors); using (catchup) using (catchup.EventBus.Errors.Subscribe(scenario.AddEventHandlingError)) using (catchup.Progress.Subscribe(s => Console.WriteLine(s))) { catchup.Run().Wait(TimeSpan.FromSeconds(30)); } } else { EventBus.PublishAsync(InitialEvents.ToArray()).Wait(); } if (scenario.EventHandlingErrors.Any()) { throw new ScenarioSetupException( "The following event handling errors occurred during projection catchup: " + string.Join("\n", scenario.EventHandlingErrors.Select(e => e.Exception.ToString()))); } }
public void Projection_write_speed_without_unit_of_work() { var eventsRead = 0; var projector1 = Projector.Create<IEvent>(e => { using (var db = new ReadModelDbContext()) { db.Set<ProductInventory>().Add(new ProductInventory { ProductName = Guid.NewGuid().ToString(), QuantityInStock = Any.Int(1, 5), QuantityReserved = 0 }); db.SaveChanges(); eventsRead++; } }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); using (var catchup = new ReadModelCatchup(projector1) { StartAtEventId = startAtEventId }) { catchup.Run(); } Console.WriteLine(new { eventsRead }); // TODO: (Write_speed_without_unit_of_work) write test Assert.Fail("Test not written yet."); }
public void Projection_write_speed_with_unit_of_work() { var eventsRead = 0; var projector1 = Projector.Create<IEvent>(e => { using (var update = this.Update()) { var db = update.Resource<ReadModelDbContext>(); db.Set<ProductInventory>().Add(new ProductInventory { ProductName = Guid.NewGuid().ToString(), QuantityInStock = Any.Int(1, 5), QuantityReserved = 0 }); db.SaveChanges(); eventsRead++; } }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); using (var catchup = new ReadModelCatchup( eventStoreDbContext: () => EventStoreDbContext(), readModelDbContext: () => ReadModelDbContext(), startAtEventId: startAtEventId, projectors: projector1)) { catchup.Run(); } Console.WriteLine(new { eventsRead }); }
public void Read_speed_for_two_specific_events() { var eventsRead = 0; var projector1 = Projector.Create<Order.ItemAdded>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector1"); var projector2 = Projector.Create<CustomerAccount.RequestedNoSpam>(e => { eventsRead++; }).Named(MethodBase.GetCurrentMethod().Name + ":projector2"); using (var catchup = new ReadModelCatchup( eventStoreDbContext: () => EventStoreDbContext(), readModelDbContext: () => ReadModelDbContext(), startAtEventId: startAtEventId, projectors: new object[] { projector1, projector2 })) { catchup.Run(); } Console.WriteLine(new { eventsRead }); }