public async Task not_run_handler_when_stream_state_has_error()
        {
            var cts                 = new CancellationTokenSource();
            var mockAwaiter         = new Mock <IHandlingManagerAwaiter>();
            var mockTaskCollection  = new Mock <IHandlingManagerTaskCollection>();
            var mockQueue           = new Mock <IHandlingQueue>();
            var mockStreamStateRepo = new Mock <IStreamStateRepo>();
            var mockHandlerRunner   = new Mock <IHandlingManagerHandlerRunner>();
            var manager             = new HandlingManager(NullStandardLogger.Instance, mockAwaiter.Object, mockStreamStateRepo.Object, mockQueue.Object, mockHandlerRunner.Object, mockTaskCollection.Object);
            var subscriberEvent     = new SubscriberEvent(null, null, 0, null, null);
            var parallelKey         = "x";
            var queueItem           = new HandlingQueueItem(parallelKey, subscriberEvent);
            var streamState         = new StreamState(0, true);     // Has error.

            mockQueue.Setup(x => x.IsEventsAvailable).Returns(true);
            mockQueue.Setup(x => x.TryDequeue(It.IsAny <IList <string> >())).Returns(queueItem);
            mockStreamStateRepo.Setup(x => x.LoadStreamStateAsync(It.IsAny <string>())).Callback(() => cts.Cancel()).ReturnsAsync(streamState);

            var timeoutToken = new CancellationTokenSource(10000).Token;
            await Task.WhenAny(new[] { manager.ManageAsync(cts.Token), timeoutToken.WaitHandle.AsTask() });

            cts.Cancel();
            if (timeoutToken.IsCancellationRequested)
            {
                throw new TimeoutException();
            }

            mockAwaiter.Verify(x => x.ResetHandlerCompletionSignal());
            mockAwaiter.VerifyNoOtherCalls();
        }
        public async Task enqueue_and_dequeue_items_with_correct_parallel_keys()
        {
            var cts = new CancellationTokenSource(10000);
            var mockQueueAwaiter = new Mock <IQueueAwaiter>();
            var maxQueueSize     = 2;
            var queue            = new HandlingQueue(mockQueueAwaiter.Object, maxQueueSize);
            var parallelKey1     = "pk1";
            var parallelKey2     = "pk2";
            var subscriberEvent1 = new SubscriberEvent(null, null, 0, null, null);
            var subscriberEvent2 = new SubscriberEvent(null, null, 0, null, null);

            Assert.False(queue.IsEventsAvailable);

            await queue.EnqueueWithWaitAsync(parallelKey1, subscriberEvent1, cts.Token);

            await queue.EnqueueWithWaitAsync(parallelKey2, subscriberEvent2, cts.Token);

            if (cts.IsCancellationRequested)
            {
                throw new TimeoutException();
            }

            Assert.True(queue.IsEventsAvailable);

            var dequeuedItem1 = queue.TryDequeue(new string[] { parallelKey2 });
            var dequeuedItem2 = queue.TryDequeue(new string[] { parallelKey1 });

            Assert.Equal(parallelKey1, dequeuedItem1.ParallelKey);
            Assert.Equal(subscriberEvent1, dequeuedItem1.SubscriberEvent);

            Assert.Equal(parallelKey2, dequeuedItem2.ParallelKey);
            Assert.Equal(subscriberEvent2, dequeuedItem2.SubscriberEvent);
        }
Beispiel #3
0
        public async Task invoke_business_event_handler()
        {
            var mockSubFactory = new Mock <ISubscriberFactory>();
            var businessEvent  = new TestEvent();
            var streamId       = "s";
            var position       = 5;
            var subEvent       = new SubscriberEvent(null, streamId, position, null, businessEvent);
            var dependencies   = new ProjectorDependencies(null, mockSubFactory.Object, null, null, null, null, null);
            var projector      = new TestProjector(dependencies);
            var token          = CancellationToken.None;
            var called         = false;

            projector.MockBusinessEventHandler = (pStreamId, pPosition, pEvent, pToken) =>
            {
                Assert.Equal(streamId, pStreamId);
                Assert.Equal(position, pPosition);
                Assert.Equal(businessEvent, pEvent);
                Assert.Equal(token, pToken);
                called = true;
                return(Task.CompletedTask);
            };

            await projector.HandleSubscriberEventAsync(subEvent, token);

            Assert.True(called);
        }
        public async Task wait_for_enqueue_when_managing_and_no_events_in_queue()
        {
            var cts                   = new CancellationTokenSource(10000);
            var mockQueue             = new Mock <ISortingQueue>();
            var mockSorter            = new Mock <ISubscriberEventSorter>();
            var mockHandlingManager   = new Mock <IHandlingManager>();
            var manager               = new SortingManager(NullStandardLogger.Instance, mockQueue.Object, mockSorter.Object, mockHandlingManager.Object);
            var subscriberEvent       = new SubscriberEvent(null, null, 0, null, null);
            var parallelKey           = "x";
            var awaitingEnqueueSignal = new ManualResetEventSlim(false);
            var mockEnqueueSignal     = new ManualResetEventSlim(false);

            mockQueue.Setup(x => x.TryDequeue(out It.Ref <SubscriberEvent> .IsAny)).Returns(false);
            mockSorter.Setup(x => x.SortSubscriberEventToParallelKey(subscriberEvent)).Returns(parallelKey);
            mockQueue.Setup(x => x.AwaitEnqueueSignalAsync()).Callback(() => awaitingEnqueueSignal.Set()).Returns(mockEnqueueSignal.WaitHandle.AsTask());

            var manageTask = manager.ManageAsync(cts.Token);

            await Task.WhenAny(new[] { awaitingEnqueueSignal.WaitHandle.AsTask(), cts.Token.WaitHandle.AsTask() });

            if (cts.IsCancellationRequested)
            {
                throw new TimeoutException();
            }

            cts.Cancel();
        }
Beispiel #5
0
 public virtual string SortSubscriberEventToParallelKey(SubscriberEvent subscriberEvent)
 {
     // Default is no parallel key, i.e. all events from the subscription stream
     // will be handled sequentially with no optimization to execute events in parallel.
     // The implementing class should override this if events can be consumed in parallel,
     // for example, projecting events that are from completely separate aggregate instances,
     // where the parallel key would be the aggregate root id, i.e. the transactional boundary.
     return(DEFAULT_PARALLEL_KEY);            // Sorting keys may not be null or empty.
 }
Beispiel #6
0
        public virtual async Task HandleSubscriberEventAsync(SubscriberEvent subscriberEvent, CancellationToken cancellationToken)
        {
            var allInterfaces = this.GetType().GetInterfaces();

            // Does nothing if no handler - event is ignored.
            if (this.GetType().GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IHandleBusinessEvent <>) && x.GetGenericArguments()[0] == subscriberEvent.ResolvedEventType))
            {
                await(Task) this.GetType().InvokeMember("HandleBusinessEventAsync", BindingFlags.InvokeMethod, null, this, new object[] { subscriberEvent.StreamId, subscriberEvent.Position, subscriberEvent.ResolvedEvent, cancellationToken });
            }
        }
        public void construct()
        {
            var parallelKey     = "pk";
            var subscriberEvent = new SubscriberEvent(null, null, 0, null, null);

            var item = new HandlingQueueItem(parallelKey, subscriberEvent);

            Assert.Equal(parallelKey, item.ParallelKey);
            Assert.Equal(subscriberEvent, item.SubscriberEvent);
        }
        public override string SortSubscriberEventToParallelKey(SubscriberEvent subscriberEvent)
        {
            if (subscriberEvent.IsResolved)
            {
                switch (subscriberEvent.ResolvedEvent)
                {
                case SalesOrderRaisedEvent e: return(e.SalesOrderId);
                }
            }

            return(base.SortSubscriberEventToParallelKey(subscriberEvent));
        }
        public override string SortSubscriberEventToParallelKey(SubscriberEvent subscriberEvent)
        {
            if (subscriberEvent.IsResolved)
            {
                switch (subscriberEvent.ResolvedEvent)
                {
                case EmailEnqueuedEvent e: return(e.EmailId.ToString());
                }
            }

            return(base.SortSubscriberEventToParallelKey(subscriberEvent));
        }
        public async Task receive_and_enqueue_subscriber_event()
        {
            var cts             = new CancellationTokenSource(10000);
            var mockQueue       = new Mock <ISortingQueue>();
            var manager         = new SortingManager(NullStandardLogger.Instance, mockQueue.Object, null, null);
            var subscriberEvent = new SubscriberEvent(null, null, 0, null, null);

            mockQueue.Setup(x => x.EnqueueWithWaitAsync(It.IsAny <SubscriberEvent>(), It.IsAny <CancellationToken>())).Returns(Task.CompletedTask);

            await manager.ReceiveSubscriberEventAsync(subscriberEvent, cts.Token);

            mockQueue.Verify(x => x.EnqueueWithWaitAsync(subscriberEvent, cts.Token));
        }
        public async Task throw_when_parallel_key_empty()
        {
            var cts             = new CancellationTokenSource(10000);
            var mockQueue       = new Mock <ISortingQueue>();
            var mockSorter      = new Mock <ISubscriberEventSorter>();
            var manager         = new SortingManager(NullStandardLogger.Instance, mockQueue.Object, mockSorter.Object, null);
            var subscriberEvent = new SubscriberEvent(null, null, 0, null, null);
            var parallelKey     = "";         // Must be empty (or null).

            mockQueue.Setup(x => x.TryDequeue(out subscriberEvent)).Returns(true);
            mockSorter.Setup(x => x.SortSubscriberEventToParallelKey(subscriberEvent)).Returns(parallelKey);

            await Assert.ThrowsAsync <ArgumentException>(() => manager.ManageAsync(cts.Token));
        }
        public async Task honor_max_queue_size()
        {
            var cts                    = new CancellationTokenSource(10000);
            var maxQueueSize           = 2;
            var mockQueueAwaiter       = new Mock <IQueueAwaiter>();
            var queue                  = new HandlingQueue(mockQueueAwaiter.Object, maxQueueSize);
            var parallelKey1           = "pk1";
            var parallelKey2           = "pk2";
            var parallelKey3           = "pk3";
            var subscriberEvent1       = new SubscriberEvent(null, null, 0, null, null);
            var subscriberEvent2       = new SubscriberEvent(null, null, 0, null, null);
            var subscriberEvent3       = new SubscriberEvent(null, null, 0, null, null);
            var enqueueuSignalSetCount = 0;
            var awaitingDequeueSignal  = new ManualResetEventSlim(true);
            var mockDequeueSignal      = new ManualResetEventSlim(false);

            mockQueueAwaiter.Setup(x => x.SetEnqueueSignal()).Callback(() => enqueueuSignalSetCount++);
            mockQueueAwaiter.Setup(x => x.AwaitDequeueSignalAsync()).Callback(() => awaitingDequeueSignal.Set()).Returns(mockDequeueSignal.WaitHandle.AsTask());

            await queue.EnqueueWithWaitAsync(parallelKey1, subscriberEvent1, cts.Token);

            await queue.EnqueueWithWaitAsync(parallelKey2, subscriberEvent2, cts.Token);

            var enqueueTask = queue.EnqueueWithWaitAsync(parallelKey3, subscriberEvent3, cts.Token);

            await Task.WhenAny(new[] { awaitingDequeueSignal.WaitHandle.AsTask(), cts.Token.WaitHandle.AsTask() });

            if (cts.Token.IsCancellationRequested)
            {
                throw new TimeoutException();
            }

            Assert.Equal(2, enqueueuSignalSetCount);
            Assert.Equal(maxQueueSize, queue.QueueCount);

            queue.TryDequeue(new string[] { });
            Assert.Equal(maxQueueSize - 1, queue.QueueCount);

            mockDequeueSignal.Set();

            await Task.WhenAny(new[] { enqueueTask, cts.Token.WaitHandle.AsTask() });

            if (cts.Token.IsCancellationRequested)
            {
                throw new TimeoutException();
            }

            Assert.Equal(maxQueueSize, queue.QueueCount);
        }
        public async Task reset_awaiter_when_success()
        {
            var mockAwaiter         = new Mock <IHandlingManagerAwaiter>();
            var mockHandler         = new Mock <ISubscriberEventHandler>();
            var mockStreamStateRepo = new Mock <IStreamStateRepo>();
            var runner          = new HandlingManagerHandlerRunner(NullStandardLogger.Instance, mockAwaiter.Object, mockStreamStateRepo.Object, mockHandler.Object);
            var subscriberEvent = new SubscriberEvent(null, null, 0, null, null);

            mockHandler.Setup(x => x.HandleSubscriberEventAsync(It.IsAny <SubscriberEvent>(), It.IsAny <CancellationToken>())).Returns(Task.CompletedTask);
            mockStreamStateRepo.Setup(x => x.SaveStreamStateAsync(It.IsAny <string>(), It.IsAny <long>(), It.IsAny <bool>())).Returns(Task.CompletedTask);

            await runner.TryRunHandlerAsync(subscriberEvent, CancellationToken.None);

            mockAwaiter.Verify(x => x.ReleaseThrottle());
            mockAwaiter.Verify(x => x.SetHandlerCompletionSignal());
        }
Beispiel #14
0
        public async Task enqueue_and_dequeue_single_item()
        {
            var cts              = new CancellationTokenSource(10000);
            var maxQueueSize     = 1;
            var mockQueueAwaiter = new Mock <IQueueAwaiter>();
            var queue            = new SortingQueue(mockQueueAwaiter.Object, maxQueueSize);
            var subscriberEvent  = new SubscriberEvent(null, null, 0, null, null);

            await queue.EnqueueWithWaitAsync(subscriberEvent, cts.Token);

            SubscriberEvent dequeuedSubscriberEvent;

            var tryResult = queue.TryDequeue(out dequeuedSubscriberEvent);

            Assert.True(tryResult);
            Assert.Equal(subscriberEvent, dequeuedSubscriberEvent);
        }
        public async Task await_throttle_and_run_handler_when_stream_state_does_not_have_error()
        {
            var cts                    = new CancellationTokenSource();
            var mockAwaiter            = new Mock <IHandlingManagerAwaiter>();
            var mockTaskCollection     = new Mock <IHandlingManagerTaskCollection>();
            var mockQueue              = new Mock <IHandlingQueue>();
            var mockStreamStateRepo    = new Mock <IStreamStateRepo>();
            var mockHandlerRunner      = new Mock <IHandlingManagerHandlerRunner>();
            var manager                = new HandlingManager(NullStandardLogger.Instance, mockAwaiter.Object, mockStreamStateRepo.Object, mockQueue.Object, mockHandlerRunner.Object, mockTaskCollection.Object);
            var businessEvent          = new TestBusinessEvent();
            var subscriberEvent        = new SubscriberEvent(null, null, 0, null, null);
            var parallelKey            = "x";
            var queueItem              = new HandlingQueueItem(parallelKey, subscriberEvent);
            var streamState            = new StreamState(0, false);  // Does NOT have error.
            var awaitingThrottleSignal = new ManualResetEventSlim(false);

            mockQueue.Setup(x => x.IsEventsAvailable).Returns(true);
            mockQueue.Setup(x => x.TryDequeue(It.IsAny <IList <string> >())).Returns(queueItem);
            mockQueue.Setup(x => x.AwaitEnqueueSignalAsync()).Callback(() => cts.Cancel()).Returns(Task.CompletedTask);             // Ensures manager can't get into an infinite loop.
            mockStreamStateRepo.Setup(x => x.LoadStreamStateAsync(It.IsAny <string>())).ReturnsAsync(streamState);
            mockAwaiter.Setup(x => x.AwaitThrottleAsync()).Callback(() => awaitingThrottleSignal.Set()).Returns(Task.CompletedTask);
            mockHandlerRunner.Setup(x => x.TryRunHandlerAsync(It.IsAny <SubscriberEvent>(), It.IsAny <CancellationToken>())).Callback(() => cts.Cancel()).Returns(Task.CompletedTask);

            var manageTask = manager.ManageAsync(cts.Token);

            var timeoutToken1 = new CancellationTokenSource(10000).Token;
            await Task.WhenAny(new[] { awaitingThrottleSignal.WaitHandle.AsTask(), timeoutToken1.WaitHandle.AsTask() });

            if (timeoutToken1.IsCancellationRequested)
            {
                cts.Cancel();
                throw new TimeoutException();
            }

            var timeoutToken2 = new CancellationTokenSource(10000).Token;
            await Task.WhenAny(new[] { manageTask, timeoutToken2.WaitHandle.AsTask() });

            cts.Cancel();
            if (timeoutToken2.IsCancellationRequested)
            {
                throw new TimeoutException();
            }

            mockHandlerRunner.Verify(x => x.TryRunHandlerAsync(subscriberEvent, cts.Token));
        }
        public async Task enqueue_and_not_dequeue_with_matching_parallel_key()
        {
            var cts = new CancellationTokenSource(10000);
            var mockQueueAwaiter  = new Mock <IQueueAwaiter>();
            var queue             = new HandlingQueue(mockQueueAwaiter.Object, 1);
            var subscriberEvent   = new SubscriberEvent(null, null, 0, null, null);
            var parallelKey       = "pk";
            var notInParallelKeys = new List <string>()
            {
                parallelKey
            };

            await queue.EnqueueWithWaitAsync(parallelKey, subscriberEvent, cts.Token);

            var dequeuedItem = queue.TryDequeue(notInParallelKeys);

            Assert.Null(dequeuedItem);
        }
Beispiel #17
0
        public void construct_with_event_not_resolved()
        {
            var regionId  = "r";
            var streamId  = "s";
            var position  = 1;
            var eventType = "x";

            var e = new SubscriberEvent(regionId, streamId, position, eventType, null);

            Assert.Equal(regionId, e.RegionId);
            Assert.Equal(streamId, e.StreamId);
            Assert.Equal(position, e.Position);
            Assert.Equal(streamId, e.SubscriptionStreamId);
            Assert.Equal(position, e.SubscriptionPosition);
            Assert.Equal(eventType, e.EventType);
            Assert.Null(e.ResolvedEventType);
            Assert.Null(e.ResolvedEvent);
            Assert.False(e.IsResolved);
        }
        public async Task run_handler_and_save_errored_stream_state()
        {
            var cts                 = new CancellationTokenSource();
            var mockAwaiter         = new Mock <IHandlingManagerAwaiter>();
            var mockHandler         = new Mock <ISubscriberEventHandler>();
            var mockStreamStateRepo = new Mock <IStreamStateRepo>();
            var runner              = new HandlingManagerHandlerRunner(NullStandardLogger.Instance, mockAwaiter.Object, mockStreamStateRepo.Object, mockHandler.Object);
            var streamId            = "s";
            var position            = 1;
            var subscriberEvent     = new SubscriberEvent(null, streamId, position, null, null);

            mockHandler.Setup(x => x.HandleSubscriberEventAsync(It.IsAny <SubscriberEvent>(), It.IsAny <CancellationToken>())).Throws(new Exception());
            mockStreamStateRepo.Setup(x => x.SaveStreamStateAsync(It.IsAny <string>(), It.IsAny <long>(), It.IsAny <bool>())).Returns(Task.CompletedTask);

            await runner.TryRunHandlerAsync(subscriberEvent, cts.Token);

            mockHandler.Verify(x => x.HandleSubscriberEventAsync(subscriberEvent, cts.Token));
            mockStreamStateRepo.Verify(x => x.SaveStreamStateAsync(streamId, position, true));
        }
        public async Task set_queue_signals()
        {
            var cts              = new CancellationTokenSource(10000);
            var maxQueueSize     = 1;
            var mockQueueAwaiter = new Mock <IQueueAwaiter>();
            var queue            = new HandlingQueue(mockQueueAwaiter.Object, maxQueueSize);
            var subscriberEvent  = new SubscriberEvent(null, null, 0, null, null);
            var parallelKey      = "pk";

            queue.TryDequeue(new string[] { });

            mockQueueAwaiter.VerifyNoOtherCalls();

            await queue.EnqueueWithWaitAsync(parallelKey, subscriberEvent, cts.Token);

            mockQueueAwaiter.Verify(x => x.SetEnqueueSignal());
            mockQueueAwaiter.VerifyNoOtherCalls();

            queue.TryDequeue(new string[] { });
            mockQueueAwaiter.Verify(x => x.SetDequeueSignal());
        }
        public async Task sort_subscriber_event_and_send_to_handling_manager()
        {
            var cts                 = new CancellationTokenSource(10000);
            var mockQueue           = new Mock <ISortingQueue>();
            var mockSorter          = new Mock <ISubscriberEventSorter>();
            var mockHandlingManager = new Mock <IHandlingManager>();
            var manager             = new SortingManager(NullStandardLogger.Instance, mockQueue.Object, mockSorter.Object, mockHandlingManager.Object);
            var subscriberEvent     = new SubscriberEvent(null, null, 0, null, null);
            var parallelKey         = "x";

            mockQueue.Setup(x => x.TryDequeue(out subscriberEvent)).Returns(true);
            mockSorter.Setup(x => x.SortSubscriberEventToParallelKey(subscriberEvent)).Returns(parallelKey);
            mockHandlingManager
            .Setup(x => x.ReceiveSubscriberEventAsync(It.IsAny <string>(), It.IsAny <SubscriberEvent>(), It.IsAny <CancellationToken>()))
            .Callback(() => cts.Cancel())
            .Returns(Task.CompletedTask);

            await manager.ManageAsync(cts.Token);

            mockHandlingManager.Verify(x => x.ReceiveSubscriberEventAsync(parallelKey, subscriberEvent, cts.Token));
        }
Beispiel #21
0
        public void construct_with_event_resolved()
        {
            var regionId          = "r";
            var streamId          = "s";
            var position          = 1;
            var eventType         = "x";
            var resolvedEventType = typeof(TestBusinessEvent);
            var resolvedEvent     = new TestBusinessEvent();

            var e = new SubscriberEvent(regionId, streamId, position, eventType, resolvedEvent);

            Assert.Equal(regionId, e.RegionId);
            Assert.Equal(streamId, e.StreamId);
            Assert.Equal(position, e.Position);
            Assert.Equal(streamId, e.SubscriptionStreamId);
            Assert.Equal(position, e.SubscriptionPosition);
            Assert.Equal(eventType, e.EventType);
            Assert.Equal(resolvedEventType, e.ResolvedEventType);
            Assert.Equal(resolvedEvent, e.ResolvedEvent);
            Assert.True(e.IsResolved);
        }
Beispiel #22
0
        public async Task set_queue_signals()
        {
            var cts              = new CancellationTokenSource(10000);
            var maxQueueSize     = 1;
            var mockQueueAwaiter = new Mock <IQueueAwaiter>();
            var queue            = new SortingQueue(mockQueueAwaiter.Object, maxQueueSize);
            var subscriberEvent  = new SubscriberEvent(null, null, 0, null, null);

            SubscriberEvent se1;

            queue.TryDequeue(out se1);

            mockQueueAwaiter.VerifyNoOtherCalls();

            await queue.EnqueueWithWaitAsync(subscriberEvent, cts.Token);

            mockQueueAwaiter.Verify(x => x.SetEnqueueSignal());
            mockQueueAwaiter.VerifyNoOtherCalls();

            SubscriberEvent se2;

            queue.TryDequeue(out se2);
            mockQueueAwaiter.Verify(x => x.SetDequeueSignal());
        }
 public Task CreateEvent(SubscriberEvent subscriptionEvent)
 {
     throw new NotImplementedException();
 }
Beispiel #24
0
 public HandlingQueueItem(string parallelKey, SubscriberEvent subscriberEvent)
 {
     ParallelKey     = parallelKey;
     SubscriberEvent = subscriberEvent;
 }