public void AutomaticallyReplaysEventsIfViewIsPurged(int numberOfCommands) { var allPotatoesView = new MongoDbViewManager <AllPotatoesView>(_mongoDatabase); _dispatcher.AddViewManager(allPotatoesView); Console.WriteLine("Processing {0} commands....", numberOfCommands); Enumerable.Range(0, numberOfCommands - 1) .ToList() .ForEach(i => _commandProcessor.ProcessCommand(new BitePotato("someid1", .01m))); var lastResult = _commandProcessor.ProcessCommand(new BitePotato("someid2", .01m)); Console.WriteLine("Waiting until {0} has been dispatched to the view...", lastResult.GetNewPosition()); allPotatoesView.WaitUntilProcessed(lastResult, TimeSpan.FromSeconds(2)).Wait(); var viewOnFirstLoad = allPotatoesView.Load(GlobalInstanceLocator.GetViewInstanceId()); Assert.That(viewOnFirstLoad, Is.Not.Null); Console.WriteLine("Purging the view!"); allPotatoesView.Purge(); Console.WriteLine("Waiting until {0} has been dispatched to the view...", lastResult.GetNewPosition()); allPotatoesView.WaitUntilProcessed(lastResult, TimeSpan.FromSeconds(4)).Wait(); var viewOnNextLoad = allPotatoesView.Load(GlobalInstanceLocator.GetViewInstanceId()); Assert.That(viewOnNextLoad, Is.Not.Null); Assert.That(viewOnNextLoad.LastGlobalSequenceNumber, Is.EqualTo(viewOnFirstLoad.LastGlobalSequenceNumber)); }
public void CanLoadAggregateRootAsInterfaceWhenItExistsAlready() { // first, make sure an aggregate root exists const string aggregateRootId = "someId"; _commandProcessor.ProcessCommand(new CustomCommand(context => { var instance = context.Create <Root>(aggregateRootId); instance.DoStuff(); })); // act var result = _commandProcessor.ProcessCommand(new CustomCommand(context => { var instance = context.Load <ICanDoStuff>(aggregateRootId); instance.DoStuff(); })); _viewManager.WaitUntilProcessed(result, TimeSpan.FromSeconds(5)).Wait(); // assert var view = _viewManager.Load(GlobalInstanceLocator.GetViewInstanceId()); Assert.That(view.EventCounts[aggregateRootId], Is.EqualTo(2)); }
public async Task ItShallNotBeSo() { var waitHandle = new ViewManagerWaitHandle(); var viewManager = new InMemoryViewManager <Wview>(); var commandProcessor = CommandProcessor.With() .EventStore(e => e.UseInMemoryEventStore()) .EventDispatcher(e => { e.UseViewManagerEventDispatcher(viewManager) .WithWaitHandle(waitHandle); }) .Options(o => o.SetMaxRetries(0)) .Create(); const string oneWootId = "oneWoot"; const string anotherWootId = "anotherWoot"; using (commandProcessor) { commandProcessor.ProcessCommand(new MakeAnotherWootDoItsThing(anotherWootId)); commandProcessor.ProcessCommand(new MakeOneWootReadAnotherWoot(oneWootId, anotherWootId)); commandProcessor.ProcessCommand(new MakeAnotherWootDoItsThing(anotherWootId)); var lastResult = commandProcessor.ProcessCommand(new MakeOneWootReadAnotherWoot(oneWootId, anotherWootId)); await waitHandle.WaitFor <Wview>(lastResult, TimeSpan.FromSeconds(10)); var instance = viewManager.Load(GlobalInstanceLocator.GetViewInstanceId()); instance.ToString(); } }
public void BasicDispatchOfSomeEvents() { var allPotatoesView = new MongoDbViewManager <AllPotatoesView>(_mongoDatabase); var potatoTimeToBeConsumedView = new MongoDbViewManager <PotatoTimeToBeConsumedView>(_mongoDatabase); _dispatcher.AddViewManager(allPotatoesView); _dispatcher.AddViewManager(potatoTimeToBeConsumedView); // act var firstPointInTime = new DateTime(1979, 3, 1, 12, 0, 0, DateTimeKind.Utc); TimeMachine.FixCurrentTimeTo(firstPointInTime); _commandProcessor.ProcessCommand(new BitePotato("potato1", 0.5m)); _commandProcessor.ProcessCommand(new BitePotato("potato2", 0.3m)); _commandProcessor.ProcessCommand(new BitePotato("potato2", 0.3m)); _commandProcessor.ProcessCommand(new BitePotato("potato3", 0.3m)); var nextPointInTime = new DateTime(1981, 6, 9, 12, 0, 0, DateTimeKind.Utc); TimeMachine.FixCurrentTimeTo(nextPointInTime); _commandProcessor.ProcessCommand(new BitePotato("potato1", 0.5m)); _commandProcessor.ProcessCommand(new BitePotato("potato2", 0.5m)); var lastPointInTime = new DateTime(1981, 6, 9, 12, 0, 0, DateTimeKind.Utc); _commandProcessor.ProcessCommand(new BitePotato("potato3", 0.8m)); Thread.Sleep(1000); // assert var allPotatoes = allPotatoesView.Load(GlobalInstanceLocator.GetViewInstanceId()); Assert.That(allPotatoes, Is.Not.Null); var potato1View = potatoTimeToBeConsumedView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato1")); var potato2View = potatoTimeToBeConsumedView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato2")); var potato3View = potatoTimeToBeConsumedView.Load(InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("potato3")); Assert.That(potato1View, Is.Not.Null); Assert.That(potato2View, Is.Not.Null); Assert.That(potato3View, Is.Not.Null); Assert.That(allPotatoes.NamesOfPotatoes.Count, Is.EqualTo(3)); Assert.That(allPotatoes.NamesOfPotatoes["potato1"], Is.EqualTo("Jeff")); Assert.That(allPotatoes.NamesOfPotatoes["potato2"], Is.EqualTo("Bunny")); Assert.That(allPotatoes.NamesOfPotatoes["potato3"], Is.EqualTo("Walter")); Assert.That(potato1View.Name, Is.EqualTo("Jeff")); Assert.That(potato1View.TimeOfCreation.ToUniversalTime(), Is.EqualTo(firstPointInTime)); Assert.That(potato1View.TimeToBeEaten, Is.EqualTo(nextPointInTime - firstPointInTime)); Assert.That(potato2View.Name, Is.EqualTo("Bunny")); Assert.That(potato2View.TimeOfCreation.ToUniversalTime(), Is.EqualTo(firstPointInTime)); Assert.That(potato2View.TimeToBeEaten, Is.EqualTo(nextPointInTime - firstPointInTime)); Assert.That(potato3View.Name, Is.EqualTo("Walter")); Assert.That(potato3View.TimeOfCreation.ToUniversalTime(), Is.EqualTo(firstPointInTime)); Assert.That(potato3View.TimeToBeEaten, Is.EqualTo(lastPointInTime - firstPointInTime)); }
public void WorksWithCustomSerializer() { _commandProcessor.ProcessCommand(new LeCommand("rootid")); _commandProcessor.ProcessCommand(new LeCommand("rootid")); var lastResult = _commandProcessor.ProcessCommand(new LeCommand("rootid")); _viewManager.WaitUntilProcessed(lastResult, TimeSpan.FromSeconds(10)).Wait(); var view = _viewManager.Load(GlobalInstanceLocator.GetViewInstanceId()); Assert.That(view.SecretBizTimes.Length, Is.EqualTo(3)); }
public void CanPurgeTheView() { // arrange PurgeTestView.StaticBadBoy = "first value"; _context.Save("id", new Event()); PurgeTestView.StaticBadBoy = "new value"; // act _viewManager.Purge(); _context.WaitForViewsToCatchUp(); // assert var view = _viewManager.Load(GlobalInstanceLocator.GetViewInstanceId()); Assert.That(view.CaughtStaticBadBoy, Is.EqualTo("new value")); }
public void CanUpdateMultipleViewsSynchronously() { var a = new InMemoryViewManager <ViewA>(); var b = new InMemoryViewManager <ViewB>(); Configure(x => x.EventDispatcher(d => d .UseSynchronousViewManangerEventDispatcher(a, b) .WithViewContext(new Dictionary <string, object> { { "Tag", new Tag() } }))); Emit(NewId <RootA>(), new EventA1()); b.Load(GlobalInstanceLocator.GetViewInstanceId()) .Tag.ShouldBe("Greetings from ViewA;Greetings from ViewB"); }
public void CanRecoverAfterTransientErrors(int eventCount, double failIntervalSeconds, double failDurationSeconds) { // arrange var eventIds = Enumerable.Range(0, eventCount).ToList(); var failCount = 0; using (var failTimer = new Timer(TimeSpan.FromSeconds(failIntervalSeconds).TotalMilliseconds)) { failTimer.Elapsed += delegate { View.Fail = true; failCount++; ThreadPool.QueueUserWorkItem(_ => { Thread.Sleep(TimeSpan.FromSeconds(failDurationSeconds)); View.Fail = false; }); }; failTimer.Start(); var events = eventIds .Select(id => new Event { EventId = id }) .ToList(); events.ForEach(e => _context.Save("someid", e)); // act _context.AddViewManager(_viewManager); _context.WaitForViewsToCatchUp(300); } Console.WriteLine(@"==================================================== Processed {0} events Failed every {1} seconds (total fail count: {2}) ====================================================", eventCount, failIntervalSeconds, failCount); // assert var viewInstance = _viewManager.Load(GlobalInstanceLocator.GetViewInstanceId()); Assert.That(viewInstance.EventIds, Is.EqualTo(eventIds)); }
public void WorksWithGlobalInstanceView() { _context.AddViewManager(_globalInstanceViewManager); _context.Save("id1", new ThisIsJustAnEvent()); _context.Save("id1", new ThisIsJustAnEvent()); _context.Save("id1", new ThisIsJustAnEvent()); _context.Save("id2", new ThisIsJustAnEvent()); _context.Save("id2", new ThisIsJustAnEvent()); _context.Save("id2", new ThisIsJustAnEvent()); _context.WaitForViewsToCatchUp(); var view = _factory.Load <GlobalInstanceViewInstance>(GlobalInstanceLocator.GetViewInstanceId()); Assert.That(view.EventCounter, Is.EqualTo(6)); }
public void AutomaticallyRegeneratesSchemaIfColumnIsMissing() { // arrange _viewManager = new MsSqlViewManager <SomeView>(_connectionString, "views", automaticallyCreateSchema: true); // schema is generated now - let's drop a column and re-initialize the view manager DropColumn("views", "ColumnA"); // act _viewManager = new MsSqlViewManager <SomeView>(_connectionString, "views", automaticallyCreateSchema: true); // assert _viewManager.Dispatch(new ThrowingViewContext(), new[] { GetAnEvent(Guid.NewGuid(), 0), GetAnEvent(Guid.NewGuid(), 1) }); var view = _viewManager.Load(GlobalInstanceLocator.GetViewInstanceId()); Assert.That(view.Events, Is.EqualTo(2)); }
public void CanTestWithDependentViewManagerEventDispatcher() { var a = new InMemoryViewManager <ViewA>(); var b = new InMemoryViewManager <ViewB>(); Configure(x => { x.EventDispatcher(d => { var context = new Dictionary <string, object> { { "Tag", new Tag() } }; d.UseViewManagerEventDispatcher(a).WithViewContext(context); d.UseDependentViewManagerEventDispatcher(b).DependentOn(a).WithViewContext(context); }); }); Emit(NewId <RootA>(), new EventA1()); b.Load(GlobalInstanceLocator.GetViewInstanceId()) .Tag.ShouldBe("Greetings from ViewA;Greetings from ViewB"); }
public static TView Load <TView>(this IViewManager <TView> viewInstance) where TView : IViewInstance <GlobalInstanceLocator> { return(viewInstance.Load(GlobalInstanceLocator.GetViewInstanceId())); }
public async Task CanInstallMultipleEventDispatchers() { var database = MongoHelper.InitializeTestDatabase(); var waiter = new ViewManagerWaitHandle(); //Brett new var commandProcessor = base.CreateCommandProcessor(config => config .EventStore(es => { es.UseMongoDb(database, "Events"); es.EnableCaching(10); }) .EventDispatcher(ed => { ed.UseViewManagerEventDispatcher(new MongoDbViewManager <ConfigTestView>(database, "view1")).WithWaitHandle(waiter).WithConfiguration(new ViewManagerEventDispatcherConfiguration(200)); ed.UseViewManagerEventDispatcher(new MongoDbViewManager <ConfigTestView>(database, "view2")).WithWaitHandle(waiter); ed.UseViewManagerEventDispatcher(new MongoDbViewManager <ConfigTestView>(database, "view3")).WithWaitHandle(waiter); ed.UseViewManagerEventDispatcher(new MongoDbViewManager <ConfigTestView>(database, "view4")).WithWaitHandle(waiter); })); //orig //var commandProcessor = CommandProcessor.With() // .Logging(l => l.UseConsole(minLevel: Logger.Level.Warn)) // .EventStore(e => // { // e.UseMongoDb(database, "Events"); // e.EnableCaching(10); // }) // .EventDispatcher(d => // { // d.UseViewManagerEventDispatcher(new MongoDbViewManager<ConfigTestView>(database, "view1")) // .WithWaitHandle(waiter) // .WithMaxDomainEventsPerBatch(200); // d.UseViewManagerEventDispatcher(new MongoDbViewManager<ConfigTestView>(database, "view2")) // .WithWaitHandle(waiter); // d.UseViewManagerEventDispatcher(new MongoDbViewManager<ConfigTestView>(database, "view3")) // .WithWaitHandle(waiter); // d.UseViewManagerEventDispatcher(new MongoDbViewManager<ConfigTestView>(database, "view4")) // .WithWaitHandle(waiter); // }) // .Create(); RegisterForDisposal(commandProcessor); Console.WriteLine("Processing 100 commands..."); 99.Times(() => { commandProcessor.ProcessCommand(new ConfigTestCommand("id1")); commandProcessor.ProcessCommand(new ConfigTestCommand("id2")); }); commandProcessor.ProcessCommand(new ConfigTestCommand("id1")); var lastResult = commandProcessor.ProcessCommand(new ConfigTestCommand("id2")); Console.WriteLine("Waiting until views have been updated"); await waiter.WaitForAll(lastResult, TimeSpan.FromSeconds(5)); Console.WriteLine("Done - checking collections"); var expectedViewCollectionNames = new[] { "view1", "view2", "view3", "view4" }; var viewCollectionNames = database.GetCollectionNames() .OrderBy(n => n) .Where(c => c.StartsWith("view") && !c.EndsWith("Position")) .ToArray(); Assert.That(viewCollectionNames, Is.EqualTo(expectedViewCollectionNames)); expectedViewCollectionNames.ToList() .ForEach(name => { var doc = database.GetCollection <ConfigTestView>(name) .FindOne(Query.EQ("_id", GlobalInstanceLocator.GetViewInstanceId())); Assert.That(doc.ProcessedEventNumbers, Is.EqualTo(Enumerable.Range(0, 200).ToArray())); Assert.That(doc.CountsByRootId["id1"], Is.EqualTo(100)); Assert.That(doc.CountsByRootId["id2"], Is.EqualTo(100)); }); }