Пример #1
0
        public bool Rebuild(Type projectionType, ProjectionVersion version, DateTime replayUntil)
        {
            DateTime startRebuildTimestamp = DateTime.UtcNow;
            int      progressCounter       = 0;

            log.Info(() => $"Start rebuilding projection `{projectionType.Name}` for version {version}. Deadline is {replayUntil}");

            var projection           = FastActivator.CreateInstance(projectionType) as IProjectionDefinition;
            var projectionEventTypes = GetInvolvedEvents(projectionType).ToList();

            projectionStore.InitializeProjectionStore(version);
            snapshotStore.InitializeProjectionSnapshotStore(version);
            var indexState = index.GetIndexState();

            if (indexState.IsPresent() == false)
            {
                return(false);
            }
            foreach (var eventType in projectionEventTypes)
            {
                log.Debug(() => $"Rebuilding projection `{projectionType.Name}` for version {version} using eventType `{eventType}`. Deadline is {replayUntil}");

                var indexId = new EventStoreIndexEventTypeId(eventType);
                IEnumerable <ProjectionCommit> indexCommits = index.EnumerateCommitsByEventType(indexId);

                foreach (var indexCommit in indexCommits)
                {
                    progressCounter++;
                    if (progressCounter % 1000 == 0)
                    {
                        log.Trace(() => $"Rebuilding projection {projectionType.Name} => PROGRESS:{progressCounter} Version:{version} EventType:{eventType} Deadline:{replayUntil} Total minutes working:{(DateTime.UtcNow - startRebuildTimestamp).TotalMinutes}. logId:{Guid.NewGuid().ToString()}");
                    }
                    // if the replay did not finish in time (specified by the AR) we need to abort.
                    if (DateTime.UtcNow >= replayUntil)
                    {
                        log.Info(() => $"Rebuilding projection `{projectionType.Name}` stopped bacause the deadline has been reached. PROGRESS:{progressCounter} Version:{version} EventType:`{eventType}` Deadline:{replayUntil}.");
                        return(false);
                    }
                    IAggregateRootId arId       = GetAggregateRootId(indexCommit.EventOrigin.AggregateRootId);
                    IEventStore      eventStore = eventStoreFactory.GetEventStore(tenantResolver.Resolve(arId));
                    EventStream      stream     = eventStore.Load(arId, theId => projectionType.GetBoundedContext().BoundedContextName);

                    foreach (AggregateCommit arCommit in stream.Commits)
                    {
                        for (int i = 0; i < arCommit.Events.Count; i++)
                        {
                            IEvent theEvent = arCommit.Events[i].Unwrap();

                            if (projectionEventTypes.Contains(theEvent.GetType().GetContractId()))
                            {
                                var origin = new EventOrigin(Convert.ToBase64String(arCommit.AggregateRootId), arCommit.Revision, i, arCommit.Timestamp);
                                projectionRepository.Save(projectionType, theEvent, origin); // overwrite
                            }
                        }
                    }
                }
            }
            log.Info(() => $"Finish rebuilding projection `{projectionType.Name}` for version {version}. Deadline was {replayUntil}");
            return(true);
        }