public async Task WaitUntilProcessed(CommandProcessingResult result, TimeSpan timeout) { if (!result.EventsWereEmitted) { return; } var mostRecentGlobalSequenceNumber = result.GetNewPosition(); var stopwatch = Stopwatch.StartNew(); var currentPosition = await GetPosition(canGetFromCache : true); while (currentPosition < mostRecentGlobalSequenceNumber) { if (stopwatch.Elapsed > timeout) { throw new TimeoutException(string.Format("View for {0} did not catch up to {1} within {2} timeout!", typeof(TViewInstance), mostRecentGlobalSequenceNumber, timeout)); } await Task.Delay(TimeSpan.FromMilliseconds(20)); currentPosition = await GetPosition(canGetFromCache : false); } }
/// <summary> /// Blocks until all views have processed the events that were emitted in the unit of work /// that generated the given <see cref="CommandProcessingResult"/>. If that does not happen before <seealso cref="timeout"/> /// has elapsed, a <see cref="TimeoutException"/> is thrown. /// </summary> public async Task WaitForAll(CommandProcessingResult result, TimeSpan timeout) { var tasks = _dispatchers .Select(d => d.WaitUntilProcessed(result, timeout)) .ToArray(); await Task.WhenAll(tasks); }
/// <summary> /// Blocks until the view for the specified view model has processed the events that were emitted in the unit of work /// that generated the given <see cref="CommandProcessingResult"/>. If that does not happen before <seealso cref="timeout"/> /// has elapsed, a <see cref="TimeoutException"/> is thrown. /// </summary> public async Task WaitFor <TViewInstance>(CommandProcessingResult result, TimeSpan timeout) where TViewInstance : IViewInstance { var tasks = _dispatchers .Select(d => d.WaitUntilProcessed <TViewInstance>(result, timeout)) .ToArray(); await Task.WhenAll(tasks); }
CommandProcessingResult GetLastResult() { var eventStore = new MongoDbEventStore(_database, "Events"); var nextGlobalSequenceNumber = eventStore.GetNextGlobalSequenceNumber(); var lastGlobalSequenceNumber = nextGlobalSequenceNumber - 1; return(CommandProcessingResult.WithNewPosition(lastGlobalSequenceNumber)); }
public async Task WaitUntilProcessed(CommandProcessingResult result, TimeSpan timeout) { if (result == null) { throw new ArgumentNullException("result"); } await Task.WhenAll(_viewManagers .Select(v => v.WaitUntilProcessed(result, timeout)) .ToArray()); }
public async Task WaitUntilProcessed <TViewInstance>(CommandProcessingResult result, TimeSpan timeout) where TViewInstance : IViewInstance { if (result == null) { throw new ArgumentNullException("result"); } await Task.WhenAll(_viewManagers .OfType <IViewManager <TViewInstance> >() .Select(v => v.WaitUntilProcessed(result, timeout)) .ToArray()); }
public async Task WaitUntilProcessed(CommandProcessingResult result, TimeSpan timeout) { if (!result.EventsWereEmitted) { return; } while (_position < result.GetNewPosition()) { await Task.Delay(100); } }
public void CanDeliverDomainEventsDirectlyWhenEverythingAlignsPerfectly() { var testViewManager = new TestViewManager(); _dispatcher.AddViewManager(testViewManager); _thisBadBoyEnsuresThatTheEventStoreIsNotUsed.Throw = true; CommandProcessingResult result = null; 10.Times(() => result = _commandProcessor.ProcessCommand(new LeCommand("someId"))); testViewManager.WaitUntilProcessed(result, TimeSpan.FromSeconds(3)).Wait(); }
/// <summary> /// Waits for views managing the specified <see cref="TViewInstance"/> to catch up with the entire history of events, timing out if that takes longer than 10 seconds /// </summary> public void WaitForViewToCatchUp <TViewInstance>(int timeoutSeconds = 10) where TViewInstance : IViewInstance { var allGlobalSequenceNumbers = History.Select(h => h.GetGlobalSequenceNumber()).ToArray(); if (!allGlobalSequenceNumbers.Any()) { return; } var result = CommandProcessingResult.WithNewPosition(allGlobalSequenceNumbers.Max()); _waitHandle.WaitFor <TViewInstance>(result, TimeSpan.FromSeconds(timeoutSeconds)).Wait(); }
/// <summary> /// Waits for views managing the specified <see cref="TViewInstance"/> to catch up with the entire history of events, timing out if that takes longer than 10 seconds /// </summary> public void WaitForViewToCatchUp <TViewInstance>(int timeoutSeconds = 10) where TViewInstance : IViewInstance { var allGlobalSequenceNumbers = History.Select(h => h.GetGlobalSequenceNumber()).ToArray(); if (!allGlobalSequenceNumbers.Any()) { return; } var result = CommandProcessingResult.WithNewPosition(allGlobalSequenceNumbers.Max()); WithEventDispatcherOfType <IAwaitableEventDispatcher>(x => x.WaitUntilProcessed <TViewInstance>(result, TimeSpan.FromSeconds(timeoutSeconds)).Wait()); }
public async Task YeahItWorks() { CommandProcessingResult lastResult = null; foreach (var i in Enumerable.Range(0, 40)) { lastResult = _commandProcessor.ProcessCommand(new IncrementNumberCommand("id1")); } await _waitHandler.WaitForAll(lastResult, TimeSpan.FromSeconds(10)); var view = _viewManager.Load("id1"); Assert.That(view.Counter, Is.EqualTo(40)); }
public async Task WaitUntilProcessed(CommandProcessingResult result, TimeSpan timeout) { if (!result.EventsWereEmitted) { return; } var stopwatch = Stopwatch.StartNew(); while (_position < result.GetNewPosition()) { await Task.Delay(100); if (stopwatch.Elapsed > timeout) { throw new TimeoutException(string.Format("oh noes, the view did not catch up within {0} timeout!", timeout)); } } }
/// <summary> /// Waits for all views to catch up with the entire history of events, timing out if that takes longer than 10 seconds /// </summary> public void WaitForViewsToCatchUp(int timeoutSeconds = 10) { var allGlobalSequenceNumbers = History.Select(h => h.GetGlobalSequenceNumber()).ToArray(); if (!allGlobalSequenceNumbers.Any()) { return; } var result = CommandProcessingResult.WithNewPosition(allGlobalSequenceNumbers.Max()); try { _waitHandle.WaitForAll(result, TimeSpan.FromSeconds(timeoutSeconds)).Wait(); } catch (TimeoutException exception) { throw new TimeoutException(string.Format(@"One or more views did not catch up within {0} s timeout Current view positions: {1}", timeoutSeconds, string.Join(Environment.NewLine, _addedViews.Select(viewManager => string.Format(" {0}: {1}", viewManager.GetPosition().ToString().PadRight(5), viewManager.GetType().FullName)))), exception); } }
public async Task YeyItWorks() { CirqusLoggerFactory.Current = new ConsoleLoggerFactory(); var mongoDatabase = MongoHelper.InitializeTestDatabase(); var firstView = new MongoDbViewManager <HeyCounter>(mongoDatabase); var secondView = new MongoDbViewManager <WordCounter>(mongoDatabase); /* ________.......------=====^^!^^=====------.......________ */ var dependentView = new MongoDbViewManager <HeyPercentageCalculator>(mongoDatabase); /* ________.......------=====^^!^^=====------.......________ */ var waitHandle = new ViewManagerWaitHandle(); var specialWaitHandle = new ViewManagerWaitHandle(); //Brett var commandProcessor = CreateCommandProcessor(config => config .EventStore(e => e.UseInMemoryEventStore()) .EventDispatcher(e => { e.UseViewManagerEventDispatcher(firstView) .WithWaitHandle(waitHandle); e.UseViewManagerEventDispatcher(secondView) .WithWaitHandle(waitHandle); e.UseDependentViewManagerEventDispatcher(dependentView) .WithWaitHandle(specialWaitHandle) .DependentOn(firstView, secondView) .WithViewContext(new Dictionary <string, object> { { "heys", mongoDatabase.GetCollection <HeyCounter>(typeof(HeyCounter).Name).AsQueryable() }, { "words", mongoDatabase.GetCollection <WordCounter>(typeof(WordCounter).Name).AsQueryable() }, }); })); //Orig //var commandProcessor = CommandProcessor.With() // .EventStore(e => e.UseInMemoryEventStore()) // .EventDispatcher(e => // { // e.UseViewManagerEventDispatcher(firstView) // .WithWaitHandle(waitHandle); // e.UseViewManagerEventDispatcher(secondView) // .WithWaitHandle(waitHandle); // e.UseDependentViewManagerEventDispatcher(dependentView) // .WithWaitHandle(specialWaitHandle) // .DependentOn(firstView, secondView) // .WithViewContext(new Dictionary<string, object> // { // {"heys", mongoDatabase.GetCollection<HeyCounter>(typeof (HeyCounter).Name).AsQueryable()}, // {"words", mongoDatabase.GetCollection<WordCounter>(typeof (WordCounter).Name).AsQueryable()}, // }); // }) // .Create(); RegisterForDisposal(commandProcessor); //Brett CommandProcessingResult result = null; Enumerable.Range(0, 100).ToList().ForEach(i => result = commandProcessor.ProcessCommand(new DoStuff("test", "hej meddig min ven " + i))); //orig //result = Enumerable.Range(0, 100) // .Select(i => commandProcessor.ProcessCommand(new DoStuff("test", "hej meddig min ven " + i))) // .Last(); await waitHandle.WaitForAll(result, TimeSpan.FromSeconds(5)); var viewId = InstancePerAggregateRootLocator.GetViewIdFromAggregateRootId("test"); var firstViewInstance = firstView.Load(viewId); var secondViewInstance = secondView.Load(viewId); Assert.That(firstViewInstance.Count, Is.EqualTo(100)); Assert.That(secondViewInstance.Count, Is.EqualTo(500)); Console.WriteLine("Waiting for dependent views to catch up..."); await specialWaitHandle.WaitForAll(result, TimeSpan.FromSeconds(5)); Console.WriteLine("DOne!"); var heyPercentageCalculator = dependentView.Load(viewId); Assert.That(heyPercentageCalculator.HeyPercentage, Is.EqualTo(20)); }
public Task WaitUntilProcessed(CommandProcessingResult result, TimeSpan timeout) { return(Task.WhenAll(_eventDispatchers.OfType <IAwaitableEventDispatcher>().Select(x => x.WaitUntilProcessed(result, timeout)))); }