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); }
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); }
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); }
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); }
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); })); }
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); }