Beispiel #1
0
        private async Task <long> StreamEventsToProjections(ExclusiveEventStoreCatchupQuery query)
        {
            long eventsProcessedOutOfBatch = 0;

            foreach (var storedEvent in query.Events)
            {
                eventsProcessedOutOfBatch++;

                IncludeReadModelsNeeding(storedEvent);

                if (cancellationDisposable.IsDisposed)
                {
                    break;
                }

                IEvent @event = null;
                var    now    = Clock.Now();

                try
                {
                    @event = await UpdateProjectorsAndCursors(
                        query,
                        storedEvent,
                        eventsProcessedOutOfBatch,
                        now);
                }
                catch (Exception ex)
                {
                    var error = @event == null
                                    ? SerializationError(ex, storedEvent)
                                    : new Domain.EventHandlingError(ex, @event: @event);

                    ReadModelUpdate.ReportFailure(
                        error,
                        createReadModelDbContext);
                }

                var status = new ReadModelCatchupStatus
                {
                    BatchCount = query.BatchMatchedEventCount,
                    NumberOfEventsProcessed = eventsProcessedOutOfBatch,
                    CurrentEventId          = storedEvent.Id,
                    EventTimestamp          = storedEvent.Timestamp,
                    StatusTimeStamp         = now,
                    CatchupName             = Name
                };

                if (status.IsEndOfBatch)
                {
                    // reset the re-entrancy flag
                    running = 0;
                    query.Dispose();
                }

                ReportStatus(status);
            }

            return(eventsProcessedOutOfBatch);
        }
Beispiel #2
0
        private static void CreateUnitOfWork(
            UnitOfWork <ReadModelUpdate> unitOfWork,
            Action <ReadModelUpdate> setSubject)
        {
            var update = new ReadModelUpdate
            {
                Transaction = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions
                {
                    IsolationLevel = IsolationLevel.ReadCommitted
                })
            };

            setSubject(update);
        }
Beispiel #3
0
 private static void CreateUnitOfWork(
     UnitOfWork<ReadModelUpdate> unitOfWork,
     Action<ReadModelUpdate> setSubject)
 {
     var update = new ReadModelUpdate
     {
         Transaction = new TransactionScope(TransactionScopeOption.RequiresNew,
                                            new TransactionOptions
                                            {
                                                IsolationLevel = IsolationLevel.ReadCommitted
                                            }, TransactionScopeAsyncFlowOption.Enabled)
     };
     setSubject(update);
 }
 /// <summary>
 /// Reports event handling errors via the specified database.
 /// </summary>
 /// <param name="bus">The bus.</param>
 /// <param name="createDbContext">The database.</param>
 /// <returns></returns>
 public static IDisposable ReportErrorsToDatabase(this IEventBus bus, Func <DbContext> createDbContext) =>
 bus.Errors.Subscribe(e => ReadModelUpdate.ReportFailure(e, createDbContext));
Beispiel #5
0
 /// <summary>
 /// Initializes the <see cref="ReadModelCatchup{TDbContext}"/> class.
 /// </summary>
 static ReadModelCatchup()
 {
     ReadModelUpdate.ConfigureUnitOfWork();
 }
Beispiel #6
0
        private async Task <long> StreamEventsToProjections(ExclusiveEventStoreCatchupQuery query)
        {
            long eventsProcessed = 0;

            foreach (var storedEvent in query.Events)
            {
                eventsProcessed++;

                IncludeReadModelsNeeding(storedEvent);

                if (cancellationDisposable.IsDisposed)
                {
                    break;
                }

                IEvent @event = null;
                var    now    = Clock.Now();

                try
                {
                    // update projectors
                    @event = storedEvent.ToDomainEvent();

                    if (@event != null)
                    {
                        using (var work = CreateUnitOfWork(@event))
                        {
                            await bus.PublishAsync(@event);

                            var infos = work.Resource <DbContext>().Set <ReadModelInfo>();

                            subscribedReadModelInfos.ForEach(i =>
                            {
                                var eventsRemaining = query.ExpectedNumberOfEvents - eventsProcessed;

                                infos.Attach(i);
                                i.LastUpdated           = now;
                                i.CurrentAsOfEventId    = storedEvent.Id;
                                i.LatencyInMilliseconds = (now - @event.Timestamp).TotalMilliseconds;
                                i.BatchRemainingEvents  = eventsRemaining;

                                if (eventsProcessed == 1)
                                {
                                    i.BatchStartTime   = now;
                                    i.BatchTotalEvents = query.ExpectedNumberOfEvents;
                                }

                                if (i.InitialCatchupStartTime == null)
                                {
                                    i.InitialCatchupStartTime = now;
                                    i.InitialCatchupEvents    = query.ExpectedNumberOfEvents;
                                }

                                if (eventsRemaining == 0 && i.InitialCatchupEndTime == null)
                                {
                                    i.InitialCatchupEndTime = now;
                                }
                            });

                            work.VoteCommit();
                        }
                    }
                    else
                    {
                        throw new SerializationException(string.Format(
                                                             "Deserialization: Event type '{0}.{1}' not found",
                                                             storedEvent.StreamName,
                                                             storedEvent.Type));
                    }
                }
                catch (Exception ex)
                {
                    var error = @event == null
                                    ? SerializationError(ex, storedEvent)
                                    : new Domain.EventHandlingError(ex, @event: @event);

                    ReadModelUpdate.ReportFailure(
                        error,
                        () => CreateReadModelDbContext());
                }

                var status = new ReadModelCatchupStatus
                {
                    BatchCount = query.ExpectedNumberOfEvents,
                    NumberOfEventsProcessed = eventsProcessed,
                    CurrentEventId          = storedEvent.Id,
                    EventTimestamp          = storedEvent.Timestamp,
                    StatusTimeStamp         = now,
                    CatchupName             = Name
                };

                if (status.IsEndOfBatch)
                {
                    // reset the re-entrancy flag
                    running = 0;
                    query.Dispose();
                }

                ReportStatus(status);
            }
            return(eventsProcessed);
        }
Beispiel #7
0
 static ProjectorExtensions()
 {
     ReadModelUpdate.ConfigureUnitOfWork();
 }
Beispiel #8
0
 /// <summary>
 /// Reports event handling errors via the specified database.
 /// </summary>
 /// <param name="bus">The bus.</param>
 /// <param name="db">The database.</param>
 /// <returns></returns>
 public static IDisposable ReportErrorsToDatabase(this IEventBus bus, Func <DbContext> db)
 {
     return(bus.Errors.Subscribe(e => ReadModelUpdate.ReportFailure(e, db)));
 }