Exemplo n.º 1
0
        public virtual async Task <QueueServiceBatchResult> FetchAndProcessDataAsync(
            Func <TData, Task <TResult> > processFunc,
            long totalCount)
        {
            var batchResult = new QueueServiceBatchResult();

            foreach (var fetchTask in DequeueMany(totalCount, Configuration.BatchSize))
            {
                IQueueMessage <TData> message = null;
                try
                {
                    message = await GetQueueExceptionPolicy()
                              .ExecuteAsync(async() => await fetchTask.ConfigureAwait(false))
                              .ConfigureAwait(false);

                    if (!Validate(message))
                    {
                        _requestValidator.HandleInvalidMessage(message, batchResult, nameof(FetchAndProcessDataAsync));
                        continue;
                    }

                    var result = await Policy.Handle <MessageFetchAndProcessException>()
                                 .WaitAndRetryAsync(GetRetrySleepDurations(Configuration.RetryInMessageProcess))
                                 .ExecuteAsync(async() => await QueueServiceMessageHelpers
                                               .ProcessMessageAsync(message, processFunc)
                                               .ConfigureAwait(false))
                                 .ConfigureAwait(false);

                    _logger.LogDebug(result.ItemDescription);

                    batchResult.SuccessCount++;
                }
                catch (MessageQueueException e)
                {
                    _logger.LogError("Error while fetching queue item. Item will remain in the queue.", e);

                    batchResult.FailureCount++;
                }
                catch (MessageFetchAndProcessException e)
                {
                    _logger.LogError(
                        "Error while processing message data. Adding the data back to the message queue for the next run.", e);

                    batchResult.FailureCount++;

                    if (message == null)
                    {
                        _logger.LogWarning("Queue message is null, skipping.");
                        continue;
                    }

                    await MessageQueue.EnqueueAsync(message.Data, message.Id).ConfigureAwait(false);
                }
            }

            return(batchResult);
        }
Exemplo n.º 2
0
        public virtual async Task <QueueServiceBatchResult> FetchAndProcessDataManyAsync(
            Func <IEnumerable <TData>, Task <int> > processFunc,
            long totalCount)
        {
            var batchResult = new QueueServiceBatchResult();

            var bag = new ConcurrentBag <IQueueMessage <TData> >();

            foreach (var fetchTask in DequeueMany(totalCount, Configuration.BatchSize))
            {
                try
                {
                    var message = await GetQueueExceptionPolicy()
                                  .ExecuteAsync(async() => await fetchTask.ConfigureAwait(false));

                    if (!Validate(message))
                    {
                        _requestValidator.HandleInvalidMessage(message, batchResult, nameof(FetchAndProcessDataManyAsync));
                        continue;
                    }

                    bag.Add(message);
                }
                catch (MessageQueueException e)
                {
                    _logger.LogError("Error while fetching queue item. Item will remain in the queue.", e);

                    batchResult.FailureCount++;
                }
            }

            foreach (var processBatch in bag.Partition(Configuration.ProcessBatchSize))
            {
                try
                {
                    var count = await QueueServiceMessageHelpers
                                .ProcessMessagesAsync(processBatch, processFunc).ConfigureAwait(false);

                    batchResult.SuccessCount += Math.Max(0, count);
                }
                catch (MessageFetchAndProcessException e)
                {
                    _logger.LogError(
                        "Error while processing messages. Adding the data back to the message queue for the next run.", e);

                    batchResult.FailureCount += processBatch.Count;

                    processBatch.ForEach(async message =>
                                         await AddDataAsync(message.Data, message.Id).ConfigureAwait(false));
                }
            }

            return(batchResult);
        }