示例#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);
        }
 /// <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));
示例#3
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);
        }
示例#4
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)));
 }