예제 #1
0
        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);
        }