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); }
private void ReportStatus(ReadModelCatchupStatus status) { try { progress.OnNext(status); } catch (Exception exception) { Debug.WriteLine(string.Format("Catchup {0}: Exception while reporting status @ {1}: {2}", Name, status, exception)); } }
private void ReportStatus(ReadModelCatchupStatus status) { try { progress.OnNext(status); } catch (Exception exception) { Debug.WriteLine($"Catchup {Name}: Exception while reporting status @ {status}: {exception}"); } }
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); }