private IEnumerable <UnwindedDomainEvent> UnwindCommit(ICommit commit) { Int32 ordinal = 1; foreach (var evt in commit.Events) { var id = commit.CheckpointToken + "_" + ordinal; UnwindedDomainEvent unwinded = new UnwindedDomainEvent(); unwinded.Id = id; unwinded.CheckpointToken = commit.CheckpointToken; unwinded.EventSequence = ordinal; unwinded.EventType = evt.Body.GetType().Name; unwinded.Event = (DomainEvent)evt.Body; //save all data from commit to the event unwinded to do enhance after load. var headers = commit.Headers; if (evt.Headers.Count > 0) { headers = commit.Headers.ToDictionary(k => k.Key, k => k.Value); foreach (var eventHeader in evt.Headers) { headers[eventHeader.Key] = eventHeader.Value; } } unwinded.CommitStamp = commit.CommitStamp; unwinded.CommitId = commit.CommitId; unwinded.Version = commit.StreamRevision; unwinded.Context = headers; yield return(unwinded); ordinal++; } }
private IEnumerable <UnwindedDomainEvent> UnwindChunk(IChunk chunk) { Changeset commit = chunk.Payload as Changeset; if (commit != null) { Int32 ordinal = 1; foreach (var evt in commit.Events) { var id = chunk.Position + "_" + ordinal; UnwindedDomainEvent unwinded = new UnwindedDomainEvent(); unwinded.Id = id; unwinded.CheckpointToken = chunk.Position; unwinded.EventSequence = ordinal; unwinded.EventType = evt.GetType().Name; unwinded.Event = evt; //save all data from commit to the event unwinded to do enhance after load. var headers = commit.Headers; unwinded.CommitStamp = (evt as DomainEvent)?.CommitStamp ?? DateTime.MinValue; unwinded.CommitId = chunk.OperationId; unwinded.Version = commit.AggregateVersion; unwinded.PartitionId = chunk.PartitionId; var newContext = new Dictionary <String, Object>(); foreach (var key in headers.Keys.Where(k => !HeaderToRemove.Contains(k))) { newContext[key] = headers[key]; } unwinded.Context = newContext; yield return(unwinded); ordinal++; } } else if (chunk.Payload != null) { var id = chunk.Position + "_1"; UnwindedDomainEvent unwinded = new UnwindedDomainEvent(); unwinded.Id = id; unwinded.CheckpointToken = chunk.Position; unwinded.EventSequence = 1; unwinded.EventType = chunk.Payload.GetType().Name; unwinded.Event = chunk.Payload; //save all data from commit to the event unwinded to do enhance after load. unwinded.CommitStamp = DateTime.MinValue; unwinded.CommitId = chunk.OperationId; unwinded.Version = 0; unwinded.PartitionId = chunk.PartitionId; unwinded.Context = new Dictionary <String, Object>(); yield return(unwinded); } }
internal async Task DispatchEventAsync(UnwindedDomainEvent unwindedEvent) { if (unwindedEvent == UnwindedDomainEvent.LastEvent) { Finished = true; _lastCheckpointRebuilded = LastCheckpointDispatched; //Set to zero metrics, we dispatched everything. return; } var chkpoint = unwindedEvent.CheckpointToken; if (chkpoint > LastCheckpointDispatched) { if (_logger.IsDebugEnabled) { _logger.DebugFormat("Discharded event {0} commit {1} because last checkpoint dispatched for slot {2} is {3}.", unwindedEvent.CommitId, unwindedEvent.CheckpointToken, SlotName, _maxCheckpointDispatched); } return; } Interlocked.Increment(ref RebuildProjectionMetrics.CountOfConcurrentDispatchingCommit); TenantContext.Enter(_config.TenantId); try { string eventName = unwindedEvent.EventType; foreach (var projection in _projections) { var cname = projection.Info.CommonName; long elapsedticks; try { QueryPerformanceCounter(out long ticks1); await projection.HandleAsync(unwindedEvent.GetEvent(), true).ConfigureAwait(false); QueryPerformanceCounter(out long ticks2); elapsedticks = ticks2 - ticks1; KernelMetricsHelper.IncrementProjectionCounterRebuild(cname, SlotName, eventName, elapsedticks); } catch (Exception ex) { _logger.FatalFormat(ex, "[Slot: {3} Projection: {4}] Failed checkpoint: {0} StreamId: {1} Event Name: {2}", unwindedEvent.CheckpointToken, unwindedEvent.PartitionId, eventName, SlotName, cname ); HealthChecks.RegisterHealthCheck($"RebuildDispatcher, slot {SlotName} - FailedCheckpoint {unwindedEvent.CheckpointToken}", () => HealthCheckResult.Unhealthy(ex) ); throw; } _metrics.Inc(cname, eventName, elapsedticks); if (_logger.IsDebugEnabled) { _logger.DebugFormat("[{3}] [{4}] Handled checkpoint {0}: {1} > {2}", unwindedEvent.CheckpointToken, unwindedEvent.PartitionId, eventName, SlotName, cname ); } } } catch (Exception ex) { _logger.ErrorFormat(ex, "Error dispathing commit id: {0}\nMessage: {1}\nError: {2}", unwindedEvent.CheckpointToken, unwindedEvent.Event, ex.Message); HealthChecks.RegisterHealthCheck($"RebuildDispatcher, slot {SlotName} - GeneralError", () => HealthCheckResult.Unhealthy(ex) ); throw; } _lastCheckpointRebuilded = chkpoint; KernelMetricsHelper.MarkEventInRebuildDispatchedCount(SlotName, 1); Interlocked.Decrement(ref RebuildProjectionMetrics.CountOfConcurrentDispatchingCommit); }