private void DoProcessQueue() { // begin read model transaction scope // get events for workitem.AggregateId // pass events to read model // commit // we might see a work item for an aggregate twice in a row // especially if we poke the queue when we receive events on // the event bus // in fact we can subscibe to events on the event bus and do our own poking var doMore = true; while (doMore) { var scope = this.scopeFactory(); using (scope) { var queue = this.queueFactory(scope); var workItems = queue.Peek(this.maxItems); var bus = new UnitOfWorkEventBus(this.context.EventBus); scope.Add(bus); foreach (var workItem in workItems) { if (this.cancel.IsCancellationRequested) { return; } var registration = this.registrations.FirstOrDefault(x => AggregateRootBase.GetAggregateTypeDescriptor(x.AggregateType) == workItem.AggregateType); if (registration != null) { try { this.ProcessWorkItem(scope, registration, bus, workItem); queue.Dequeue(workItem); } catch (Exception ex) { // TODO: handle sqlite busy exceptions var topic = new DomainTopic(registration.AggregateType, workItem.Identity); this.context.EventBus.Publish(new DomainNotification(topic, new ReadModelBuilderFaultedEvent(workItem.Identity, ex))); throw; } } } scope.Commit(); doMore = workItems.Count == this.maxItems; } } }
private void EnqueueReadModels(IReadModelQueueProducer queue, string aggregateType, IList <IAggregateEvent> events) { if (queue != null) { var groupedEvents = from evt in events group evt by evt.AggregateId into g select new { RootId = g.Key, Version = g.Min(x => x.Version) }; foreach (var g in groupedEvents) { var workItem = queue.Enqueue(g.RootId, aggregateType, g.Version); if (workItem != null) { var topic = new DomainTopic(this.registration.AggregateType, g.RootId); this.eventBus.Publish(new DomainNotification(topic, workItem)); } } } }
private void EnqueueReadModels(IReadModelQueueProducer queue, string aggregateType, IList<IAggregateEvent> events) { if (queue != null) { var groupedEvents = from evt in events group evt by evt.AggregateId into g select new { RootId = g.Key, Version = g.Min(x => x.Version)}; foreach (var g in groupedEvents) { var workItem = queue.Enqueue(g.RootId, aggregateType, g.Version); if (workItem != null) { var topic = new DomainTopic(this.registration.AggregateType, g.RootId); this.eventBus.Publish(new DomainNotification(topic, workItem)); } } } }