private Task <(bool isComplete, IEnumerable <decimal>)> ProduceProviderFundingValues(CancellationToken token,
                                                                                             dynamic context)
        {
            BatchProfileRequestContext batchProfileRequestContext = (BatchProfileRequestContext)context;

            while (batchProfileRequestContext.HasPages)
            {
                return(Task.FromResult((false, batchProfileRequestContext.NextPage().AsEnumerable())));
            }

            return(Task.FromResult((true, ArraySegment <decimal> .Empty.AsEnumerable())));
        }
        public async Task <IActionResult> ProcessProfileAllocationBatchRequest(ProfileBatchRequest profileBatchRequest)
        {
            Guard.ArgumentNotNull(profileBatchRequest, nameof(ProfileBatchRequest));

            ValidationResult validationResult = await _batchRequestValidation.ValidateAsync(profileBatchRequest);

            if (!validationResult.IsValid)
            {
                return(validationResult.AsBadRequest());
            }

            try
            {
                FundingStreamPeriodProfilePattern profilePattern = await GetProfilePattern(profileBatchRequest);

                if (profilePattern == null)
                {
                    _logger.Error("Unable to find profile pattern for FundingStream = {fundingStreamId}, FundingPeriodId={FundingPeriodId}, FundingLineCode={FundingLineCode}, ProfilePatternKey={ProfilePatternKey}, ProviderType={ProviderType}, ProviderSubType={ProviderSubType}",
                                  profileBatchRequest.FundingStreamId,
                                  profileBatchRequest.FundingPeriodId,
                                  profileBatchRequest.FundingLineCode,
                                  profileBatchRequest.ProfilePatternKey,
                                  profileBatchRequest.ProviderType,
                                  profileBatchRequest.ProviderSubType);
                }

                BatchProfileRequestContext batchProfileRequestContext = new BatchProfileRequestContext(profilePattern,
                                                                                                       profileBatchRequest,
                                                                                                       5);

                IProducerConsumer producerConsumer = _producerConsumerFactory.CreateProducerConsumer(ProduceProviderFundingValues,
                                                                                                     ProfileProviderFundingValues,
                                                                                                     10,
                                                                                                     10,
                                                                                                     _logger);

                await producerConsumer.Run(batchProfileRequestContext);

                return(new OkObjectResult(batchProfileRequestContext.Responses.ToArray()));
            }
            catch (Exception ex)
            {
                LogError(ex, profileBatchRequest);

                throw;
            }
        }
        private Task ProfileProviderFundingValues(CancellationToken token,
                                                  dynamic context,
                                                  IEnumerable <decimal> providerFundingValues)
        {
            BatchProfileRequestContext batchProfileRequestContext = (BatchProfileRequestContext)context;

            foreach (decimal providerFundingValue in providerFundingValues)
            {
                ProfileBatchRequest request = batchProfileRequestContext.Request;

                AllocationProfileResponse allocationProfileResponse = ProfileAllocation(request,
                                                                                        batchProfileRequestContext.ProfilePattern,
                                                                                        providerFundingValue);

                batchProfileRequestContext.AddResponse(
                    new BatchAllocationProfileResponse(request.GetFundingValueKey(providerFundingValue),
                                                       providerFundingValue,
                                                       allocationProfileResponse));
            }

            return(Task.CompletedTask);
        }