private async Task ExecuteAsync(CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) { _logger.LogInformation($"{nameof(StoreProjector<TProjection>)}.{nameof(ExecuteAsync)} was cancelled before execution"); cancellationToken.ThrowIfCancellationRequested(); } using (var context = _projectionDbContextFactory.Create()) { var state = await context.ProjectionStates.FindAsync(_name); if (state == null) { state = new ProjectionState { Name = _name, CreatedDate = DateTimeOffset.UtcNow, Position = 0 }; context.ProjectionStates.Add(state); await context.SaveChangesAsync(cancellationToken); } while (!cancellationToken.IsCancellationRequested) { try { await context.Entry(state).ReloadAsync(); var page = await _eventStore.GetEventsAsync(state.Position); foreach (var @event in page.Events) { await _projectionManager.HandleAsync(@event.Payload); } if (state.Position == page.Offset) { await Task.Delay(_options.Value.Interval); } else { state.Position = page.Offset; state.LastModifiedDate = DateTimeOffset.UtcNow; await context.SaveChangesAsync(); } } catch (Exception ex) { _logger.LogCritical(ex, $"Process '{typeof(TProjection).Name}' failed at postion '{state.Position}' due to an unexpected error. See exception details for more information."); break; } } } }