Пример #1
0
        public async Task TestBatchFlowSubJobsAsync()
        {
            var root = await _client.CreateNewJobAsync(new AddJobDto("root"));

            var addSubDto = new BatchAddJobDto()
            {
                Children    = Enumerable.Range(0, 1000).Select(s => new AddJobDto(s.ToString())).ToList(),
                ParentJobId = root.JobId
            };
            var errorRes = await _client.BatchAddChildrenAsync(addSubDto);

            Assert.AreEqual(false, errorRes.Any());
            var updateJobBlock = new ActionBlock <long>(async jobId =>
            {
                await _client.UpdateJobStatesAsync(jobId, new UpdateJobStateDto(JobState.Running));
                await _client.UpdateJobStatesAsync(jobId, new UpdateJobStateDto(JobState.RanToCompletion));
            },
                                                        Helper.GetOutOfGrainExecutionOptions());

            foreach (var child in addSubDto.Children)
            {
                await updateJobBlock.PostToBlockUntilSuccessAsync(child.JobId.Value);
            }

            updateJobBlock.Complete();
            await updateJobBlock.Completion;
            await _client.UpdateJobStatesAsync(root.JobId, new UpdateJobStateDto(JobState.Running));

            await _client.UpdateJobStatesAsync(root.JobId, new UpdateJobStateDto(JobState.RanToCompletion));
        }
Пример #2
0
        private async Task ManipulateBufferAsync(IEnumerable <AddToBufferDto> bufferedGrains, bool syncState = true)
        {
            var flushAction = new ActionBlock <AddToBufferDto>(async item =>
            {
                switch (item.GrainType)
                {
                case BufferedGrainInterfaceType.JobGrain:
                    await _client.GetGrain <IJobGrainInMem>(item.GrainIntId).DeactivateAsync(syncState);
                    break;

                case BufferedGrainInterfaceType.DescendantsRefGrain:
                    await _client.GetGrain <IDescendantsRefGrainInMem>(item.GrainIntId).DeactivateAsync(syncState);
                    break;

                case BufferedGrainInterfaceType.JobTreeStatisticsGrain:
                    await _client.GetGrain <IJobTreeStatisticsGrainInMem>(item.GrainIntId)
                    .DeactivateAsync(syncState);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }, Helper.GetOutOfGrainExecutionOptions());

            foreach (var item in bufferedGrains)
            {
                await flushAction.PostToBlockUntilSuccessAsync(item);
            }

            flushAction.Complete();
            await flushAction.Completion;
        }
Пример #3
0
        private async Task MergeShardingIndexAsync()
        {
            try
            {
                var current      = DateTimeOffset.Now;
                var deleteAction = new ActionBlock <ITableEntity>(
                    async entity => await Client.GetTableReference(_tableName)
                    .ExecuteAsync(TableOperation.Delete(entity)),
                    Helper.GetOutOfGrainExecutionOptions());
                var timeIndexSeq =
                    Helper.GetTimeIndexRange(current.AddHours(-_indexConfig.TrackTimeIndexCount),
                                             current);
                foreach (var index in timeIndexSeq)
                {
                    var token        = new TableContinuationToken();
                    var shardGrain   = GrainFactory.GetGrain <IShardJobIndexGrain>(index);
                    var aggregator   = GrainFactory.GetGrain <IAggregateJobIndexGrain>(index);
                    var indexResults = new List <JobIndexInternal>();
                    while (token != null && indexResults.Count < _indexConfig.MaxRoundSize)
                    {
                        var result = await shardGrain.FetchWithTokenAsync(token);

                        token = result.ContinuationToken;
                        if (result.Results?.Count > 0)
                        {
                            indexResults.AddRange(result.Results);
                        }
                    }

                    if (indexResults.Count > 0)
                    {
                        await aggregator.MergeIntoIndicesAsync(indexResults);
                    }

                    foreach (var entity in indexResults)
                    {
                        await deleteAction.PostToBlockUntilSuccessAsync(
                            new TableEntity(entity.PartitionKey, entity.RowKey)
                        {
                            ETag = "*"
                        });
                    }

                    _logger.Info($"Merged index to {index}, count: {indexResults.Count}");
                }

                deleteAction.Complete();
                await deleteAction.Completion;
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"Error in {nameof(MergeShardingIndexAsync)}");
            }

            SharedData.LastMergeTimePoint = DateTimeOffset.Now;
        }
Пример #4
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    var current      = DateTimeOffset.Now;
                    var deleteAction = new ActionBlock <TableEntity>(
                        entity => Client.GetTableReference(_tableName).ExecuteAsync(TableOperation.Delete(entity)),
                        Helper.GetOutOfGrainExecutionOptions());
                    var timeIndexSeq =
                        Helper.GetTimeIndexRange(current.AddHours(-_indexConfig.TrackTimeIndexCount),
                                                 current);
                    foreach (var index in timeIndexSeq)
                    {
                        var token        = new TableContinuationToken();
                        var shardGrain   = _client.GetGrain <IShardJobIndexGrain>(index);
                        var aggregator   = _client.GetGrain <IAggregateJobIndexGrain>(index);
                        var indexResults = new List <JobIndexInternal>();
                        while (token != null && indexResults.Count < _indexConfig.MaxRoundSize)
                        {
                            var result = await shardGrain.FetchWithTokenAsync(token);

                            token = result.ContinuationToken;
                            if (result.Results?.Count > 0)
                            {
                                indexResults.AddRange(result.Results);
                            }
                        }
                        if (indexResults.Count > 0)
                        {
                            await aggregator.MergeIntoIndicesAsync(indexResults);
                        }
                        foreach (var entity in indexResults)
                        {
                            await deleteAction.PostToBlockUntilSuccessAsync(
                                new TableEntity(entity.PartitionKey, entity.RowKey)
                            {
                                ETag = "*"
                            });
                        }
                    }

                    deleteAction.Complete();
                    await deleteAction.Completion;
                }
                catch (Exception e)
                {
                    _logger.LogError(e, $"Error in {nameof(MergeJobIndexWorker)}");
                }

                await Task.Delay(_indexConfig.IndexMergeInterval, stoppingToken);
            }
        }
        public async Task <ReturnQueryIndexDto> QueryJobsAsync(QueryJobIndexDto dto)
        {
            if (dto.Start > dto.End)
            {
                throw new InvalidOperationException("the start date cannot be greater than the end date");
            }

            if (dto.PageNumber <= 0)
            {
                dto.PageNumber = 1;
            }

            if (dto.PageSize <= 0)
            {
                dto.PageSize = 10;
            }

            var timeIndices       = Helper.GetTimeIndexRange(dto.Start, dto.End);
            var result            = new ConcurrentDictionary <long, JobIndexInternal>();
            var queryIndicesBlock = new ActionBlock <string>(
                async index =>
            {
                var readOnlyGrainIndices =
                    await _client.GetGrain <IAggregateJobIndexGrain>(index).QueryAsync(dto.Predicate);
                foreach (var innerIndex in readOnlyGrainIndices)
                {
                    result[innerIndex.JobId] = innerIndex;
                }
            }, Helper.GetOutOfGrainExecutionOptions());

            foreach (var index in timeIndices)
            {
                await queryIndicesBlock.PostToBlockUntilSuccessAsync(index);
            }

            queryIndicesBlock.Complete();
            await queryIndicesBlock.Completion;

            return(new ReturnQueryIndexDto
            {
                Indices = _mapper.Map <List <JobIndex> >(result.Values
                                                         .OrderByDescending(s => s.JobId)
                                                         .Skip((dto.PageNumber - 1) * dto.PageNumber)
                                                         .Take(dto.PageSize)
                                                         .ToList()),
                IndexGrainHit = timeIndices.Count,
                TotalCount = result.Count
            });
        }
        public async Task <List <JobEntity> > BatchGetJobEntitiesAsync(IEnumerable <long> jobIds)
        {
            var jobs = new ConcurrentBag <JobEntityState>();
            var getJobInfoProcessor = new ActionBlock <long>(async jobId =>
            {
                var jobGrain = _client.GetGrain <IJobGrain>(jobId);
                jobs.Add(await jobGrain.GetJobAsync());
            }, Helper.GetOutOfGrainExecutionOptions());

            foreach (var childJobId in jobIds)
            {
                await getJobInfoProcessor.PostToBlockUntilSuccessAsync(childJobId);
            }

            getJobInfoProcessor.Complete();
            await getJobInfoProcessor.Completion;

            return(_mapper.Map <List <JobEntity> >(jobs.OrderByDescending(s => s.JobId).ToList()));
        }
        public async Task <Dictionary <long, JobTreeStatistics> > GetJobStatisticsListByIdsAsync(IEnumerable <long> ids)
        {
            var statisticsContainer    = new ConcurrentBag <JobTreeStatistics>();
            var getStatisticsProcessor = new ActionBlock <long>(async jobId =>
            {
                var statistics = await GetJobStatisticsByIdAsync(jobId);
                statisticsContainer.Add(statistics);
            }, Helper.GetOutOfGrainExecutionOptions());

            foreach (var id in ids)
            {
                await getStatisticsProcessor.PostToBlockUntilSuccessAsync(id);
            }

            getStatisticsProcessor.Complete();
            await getStatisticsProcessor.Completion;

            return(statisticsContainer.ToDictionary(s => s.JobId, s => s));
        }
        public async Task <List <JobIndexInternal> > QueryAsync(string queryStr)
        {
            var queryResult      = new ConcurrentBag <JobIndexInternal>();
            var queryActionBlock = new ActionBlock <int>(async index =>
            {
                var grain = GrainFactory.GetGrain <IRollingJobIndexGrain>(Helper.GetRollingIndexId(this.GetPrimaryKeyString(), index));
                foreach (var item in await grain.QueryAsync(queryStr))
                {
                    queryResult.Add(item);
                }
            }, Helper.GetGrainInternalExecutionOptions());

            for (var i = 0; i <= State.RollingIndexCount; i++)
            {
                await queryActionBlock.PostToBlockUntilSuccessAsync(i);
            }

            queryActionBlock.Complete();
            await queryActionBlock.Completion;

            return(queryResult.ToList());
        }
Пример #9
0
        public async Task <List <JobEntity> > GetDescendantEntitiesAsync(long id)
        {
            await _client.GetGrain <IJobGrain>(id).GetJobEntityAsync();

            var childrenIds = await _client.GetGrain <IDescendantsRefGrain>(id).GetChildrenAsync();

            var jobs = new ConcurrentBag <JobEntityState>();
            var getJobInfoProcessor = new ActionBlock <long>(async jobId =>
            {
                var jobGrain = _client.GetGrain <IJobGrain>(jobId);
                jobs.Add(await jobGrain.GetJobEntityAsync());
            }, Helper.GetOutOfGrainExecutionOptions());

            foreach (var childJobId in childrenIds)
            {
                await getJobInfoProcessor.PostToBlockUntilSuccessAsync(childJobId);
            }

            getJobInfoProcessor.Complete();
            await getJobInfoProcessor.Completion;

            return(_mapper.Map <List <JobEntity> >(jobs.OrderBy(s => s.JobId).ToList()));
        }