public EventConsumerGrainTests()
        {
            grainState.Value.Position = initialPosition;

            consumerName = eventConsumer.GetType().Name;

            A.CallTo(() => eventStore.CreateSubscription(A <IEventSubscriber> .Ignored, A <string> .Ignored, A <string> .Ignored))
            .Returns(eventSubscription);

            A.CallTo(() => eventConsumer.Name)
            .Returns(consumerName);

            A.CallTo(() => eventConsumer.Handles(A <StoredEvent> .Ignored))
            .Returns(true);

            A.CallTo(() => formatter.Parse(eventData, null))
            .Returns(envelope);

            sut = new MyEventConsumerGrain(
                x => eventConsumer,
                grainState,
                eventStore,
                formatter,
                log);
        }
        public void Should_handle_if_any_consumer_handles()
        {
            var stored = new StoredEvent("Stream", "1", 1, new EventData("Type", new EnvelopeHeaders(), "Payload"));

            A.CallTo(() => consumer1.Handles(stored))
            .Returns(false);

            A.CallTo(() => consumer2.Handles(stored))
            .Returns(true);

            var sut = new CompoundEventConsumer("consumer-name", consumer1, consumer2);

            var result = sut.Handles(stored);

            Assert.True(result);
        }
Пример #3
0
        public EventConsumerGrainTests()
        {
            grainState.Value = new EventConsumerState
            {
                Position = initialPosition
            };

            consumerName = eventConsumer.GetType().Name;

            A.CallTo(() => eventStore.CreateSubscription(A <IEventSubscriber> ._, A <string> ._, A <string> ._))
            .Returns(eventSubscription);

            A.CallTo(() => eventConsumer.Name)
            .Returns(consumerName);

            A.CallTo(() => eventConsumer.Handles(A <StoredEvent> ._))
            .Returns(true);

            A.CallTo(() => eventConsumer.On(A <IEnumerable <Envelope <IEvent> > > ._))
            .Invokes((IEnumerable <Envelope <IEvent> > events) =>
            {
                foreach (var @event in events)
                {
                    eventConsumer.On(@event).Wait();
                }
            });

            A.CallTo(() => eventSubscription.Sender)
            .Returns(eventSubscription);

            storedEvent = new StoredEvent("Stream", Guid.NewGuid().ToString(), 123, eventData);

            A.CallTo(() => formatter.ParseIfKnown(storedEvent))
            .Returns(envelope);

            var log = A.Fake <ILogger <EventConsumerGrain> >();

            sut = new MyEventConsumerGrain(
                x => eventConsumer,
                grainState,
                eventStore,
                formatter,
                log);
        }
Пример #4
0
        public EventConsumerGrainTests()
        {
            grainState.Value = new EventConsumerState
            {
                Position = initialPosition
            };

            consumerName = eventConsumer.GetType().Name;

            A.CallTo(() => eventStore.CreateSubscription(A <IEventSubscriber> ._, A <string> ._, A <string> ._))
            .Returns(eventSubscription);

            A.CallTo(() => eventConsumer.Name)
            .Returns(consumerName);

            A.CallTo(() => eventConsumer.Handles(A <StoredEvent> ._))
            .Returns(true);

            A.CallTo(() => eventConsumer.On(A <IEnumerable <Envelope <IEvent> > > ._))
            .Invokes((IEnumerable <Envelope <IEvent> > events) =>
            {
                foreach (var @event in events)
                {
                    eventConsumer.On(@event).Wait();
                }
            });

            A.CallTo(() => eventSubscription.Sender)
            .Returns(eventSubscription);

            A.CallTo(() => formatter.ParseIfKnown(A <StoredEvent> .That.Matches(x => x.Data == eventData)))
            .Returns(envelope);

            sut = new MyEventConsumerGrain(
                x => eventConsumer,
                grainState,
                eventStore,
                formatter,
                log);
        }
Пример #5
0
        public EventConsumerGrainTests()
        {
            state.Position = initialPosition;

            consumerName = eventConsumer.GetType().Name;

            A.CallTo(() => store.WithSnapshots(A <Type> .Ignored, consumerName, A <HandleSnapshot <EventConsumerState> > .Ignored))
            .Invokes(new Action <Type, string, HandleSnapshot <EventConsumerState> >((t, key, a) =>
            {
                apply = a;
            }))
            .Returns(persistence);

            A.CallTo(() => eventStore.CreateSubscription(A <IEventSubscriber> .Ignored, A <string> .Ignored, A <string> .Ignored))
            .Returns(eventSubscription);

            A.CallTo(() => eventConsumer.Name)
            .Returns(consumerName);

            A.CallTo(() => eventConsumer.Handles(A <StoredEvent> .Ignored))
            .Returns(true);

            A.CallTo(() => persistence.ReadAsync(EtagVersion.Any))
            .Invokes(new Action <long>(s => apply(state)));

            A.CallTo(() => persistence.WriteSnapshotAsync(A <EventConsumerState> .Ignored))
            .Invokes(new Action <EventConsumerState>(s => state = s));

            A.CallTo(() => formatter.Parse(eventData, null))
            .Returns(envelope);

            sut = new MyEventConsumerGrain(
                x => eventConsumer,
                store,
                eventStore,
                formatter,
                log);
        }
Пример #6
0
        public Task OnEventAsync(Immutable <IEventSubscription> subscription, Immutable <StoredEvent> storedEvent)
        {
            if (subscription.Value != currentSubscription)
            {
                return(TaskHelper.Done);
            }

            return(DoAndUpdateStateAsync(async() =>
            {
                if (eventConsumer.Handles(storedEvent.Value))
                {
                    var @event = ParseKnownEvent(storedEvent.Value);

                    if (@event != null)
                    {
                        await DispatchConsumerAsync(@event);
                    }
                }

                state.Value = state.Value.Handled(storedEvent.Value.EventPosition);
            }));
        }
Пример #7
0
        public BatchSubscriber(
            EventConsumerGrain grain,
            IEventDataFormatter eventDataFormatter,
            IEventConsumer eventConsumer,
            Func <IEventSubscriber, IEventSubscription> factory,
            TaskScheduler scheduler)
        {
            this.eventDataFormatter = eventDataFormatter;

            var batchSize  = Math.Max(1, eventConsumer !.BatchSize);
            var batchDelay = Math.Max(100, eventConsumer.BatchDelay);

            var parse = new TransformBlock <Job, Job>(job =>
            {
                if (job.StoredEvent != null)
                {
                    job.ShouldHandle = eventConsumer.Handles(job.StoredEvent);
                }

                if (job.ShouldHandle)
                {
                    try
                    {
                        job.Event = ParseKnownEvent(job.StoredEvent !);
                    }
                    catch (Exception ex)
                    {
                        job.Exception = ex;
                    }
                }

                return(job);
            }, new ExecutionDataflowBlockOptions
            {
                BoundedCapacity        = batchSize,
                MaxDegreeOfParallelism = 1,
                MaxMessagesPerTask     = 1
            });

            var buffer = AsyncHelper.CreateBatchBlock <Job>(batchSize, batchDelay, new GroupingDataflowBlockOptions
            {
                BoundedCapacity = batchSize * 2
            });

            var handle = new ActionBlock <IList <Job> >(async jobs =>
            {
                foreach (var jobsBySender in jobs.GroupBy <Job, object>(x => x.Sender))
                {
                    var sender = jobsBySender.Key;

                    if (ReferenceEquals(sender, eventSubscription.Sender))
                    {
                        var exception = jobs.FirstOrDefault(x => x.Exception != null)?.Exception;

                        if (exception != null)
                        {
                            await grain.OnErrorAsync(Sender, exception);
                        }
                        else
                        {
                            await grain.OnEventsAsync(Sender, GetEvents(jobsBySender), GetPosition(jobsBySender));
                        }
                    }
                }
            },
                                                        new ExecutionDataflowBlockOptions
            {
                BoundedCapacity        = 2,
                MaxDegreeOfParallelism = 1,
                MaxMessagesPerTask     = 1,
                TaskScheduler          = scheduler
            });

            parse.LinkTo(buffer, new DataflowLinkOptions
            {
                PropagateCompletion = true
            });

            buffer.LinkTo(handle, new DataflowLinkOptions
            {
                PropagateCompletion = true
            });

            pipelineStart = parse;
            pipelineEnd   = handle;

            eventSubscription = factory(this);
        }