示例#1
0
        private async Task <bool> RebuildEventsAsync(string eventTypeId, IClusterOperations cluster, CancellationToken cancellationToken)
        {
            RebuildProjection_JobData.EventPaging paging = Data.EventTypePaging.Where(et => et.Type.Equals(eventTypeId, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

            unchecked
            {
                ulong pagingProcessedCount = Data.EventTypePaging.Select(p => p.ProcessedCount).DefaultIfEmpty().Aggregate((x, y) => x + y);
                progressTracker.Processed = pagingProcessedCount;
            }

            string paginationToken = paging?.PaginationToken;
            LoadIndexRecordsResult indexRecordsResult = await eventToAggregateIndex.EnumerateRecordsAsync(eventTypeId, paginationToken).ConfigureAwait(false); // TODO: Think about cassandra exception here. Such exceptions MUST be handled in the concrete impl of the IndexStore

            IEnumerable <EventStream> eventStreams = await rebuildingRepository.LoadEventsAsync(indexRecordsResult.Records, Data.Version).ConfigureAwait(false);

            await rebuildingRepository.SaveAggregateCommitsAsync(eventStreams, Data).ConfigureAwait(false);

            await NotifyClusterAsync(eventTypeId, indexRecordsResult.PaginationToken, cluster, cancellationToken).ConfigureAwait(false);

            var hasMoreRecords = indexRecordsResult.Records.Any();

            return(hasMoreRecords);
        }
示例#2
0
        protected override async Task <JobExecutionStatus> RunJobAsync(IClusterOperations cluster, CancellationToken cancellationToken = default)
        {
            Dictionary <int, string> processedAggregates = new Dictionary <int, string>();

            string eventTypeId    = Data.SourceEventTypeId;
            bool   hasMoreRecords = true;

            while (hasMoreRecords && Data.IsCompleted == false)
            {
                string paginationToken = Data.EventTypePaging?.PaginationToken;
                LoadIndexRecordsResult indexRecordsResult = await eventToAggregateIndex.EnumerateRecordsAsync(eventTypeId, paginationToken).ConfigureAwait(false);

                IEnumerable <IndexRecord> indexRecords = indexRecordsResult.Records;
                Type          publicEventType          = typeof(IPublicEvent);
                ReplayOptions opt = new ReplayOptions()
                {
                    AggregateIds = indexRecordsResult.Records.Select(indexRecord => AggregateUrn.Parse(Convert.ToBase64String(indexRecord.AggregateRootId), Urn.Base64)),
                    ShouldSelect = commit =>
                    {
                        bool result = (from publicEvent in commit.PublicEvents
                                       let eventType = publicEvent.GetType()
                                                       where publicEventType.IsAssignableFrom(eventType)
                                                       where eventType.GetContractId().Equals(eventTypeId)
                                                       select publicEvent)
                                      .Any();

                        return(result);
                    },
                    After  = Data.After,
                    Before = Data.Before
                };
                LoadAggregateCommitsResult foundAggregateCommits = await eventStorePlayer.LoadAggregateCommitsAsync(opt).ConfigureAwait(false);

                foreach (AggregateCommit arCommit in foundAggregateCommits.Commits)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        logger.Info(() => $"Job has been cancelled.");
                        return(JobExecutionStatus.Running);
                    }

                    foreach (IPublicEvent publicEvent in arCommit.PublicEvents)
                    {
                        if (publicEvent.GetType().GetContractId().Equals(eventTypeId))
                        {
                            var headers = new Dictionary <string, string>()
                            {
                                { MessageHeader.RecipientBoundedContext, Data.RecipientBoundedContext },
                                { MessageHeader.RecipientHandlers, Data.RecipientHandlers }
                            };
                            publicEventPublisher.Publish(publicEvent, headers);
                        }
                    }
                }

                var progress = new ReplayPublicEvents_JobData.EventTypePagingProgress(eventTypeId, indexRecordsResult.PaginationToken, 0, 0);
                Data.MarkEventTypeProgress(progress);
                Data.Timestamp = DateTimeOffset.UtcNow;
                Data           = await cluster.PingAsync(Data, cancellationToken).ConfigureAwait(false);

                hasMoreRecords = indexRecordsResult.Records.Any();
            }

            Data.IsCompleted = true;
            Data.Timestamp   = DateTimeOffset.UtcNow;

            Data = await cluster.PingAsync(Data).ConfigureAwait(false);

            logger.Info(() => $"The job has been completed.");

            return(JobExecutionStatus.Completed);
        }