public async Task BuildMetrics(long ukprn, long jobId, short academicYear, byte collectionPeriod, CancellationToken cancellationToken) { try { logger.LogDebug($"Building metrics for job: {jobId}, provider: {ukprn}, Academic year: {academicYear}, Collection period: {collectionPeriod}"); var stopwatch = Stopwatch.StartNew(); var submissionSummary = submissionSummaryFactory.Create(ukprn, jobId, academicYear, collectionPeriod); var dcEarningsTask = dcMetricsDataContextFactory.CreateContext(academicYear).GetEarnings(ukprn, academicYear, collectionPeriod, cancellationToken); var dasEarningsTask = submissionRepository.GetDasEarnings(ukprn, jobId, cancellationToken); var dataLocksTask = submissionRepository.GetDataLockedEarnings(ukprn, jobId, cancellationToken); var dataLocksTotalTask = submissionRepository.GetDataLockedEarningsTotal(ukprn, jobId, cancellationToken); var dataLocksAlreadyPaid = submissionRepository.GetAlreadyPaidDataLockedEarnings(ukprn, jobId, cancellationToken); var requiredPaymentsTask = submissionRepository.GetRequiredPayments(ukprn, jobId, cancellationToken); var heldBackCompletionAmountsTask = submissionRepository.GetHeldBackCompletionPaymentsTotal(ukprn, jobId, cancellationToken); var yearToDateAmountsTask = submissionRepository.GetYearToDatePaymentsTotal(ukprn, academicYear, collectionPeriod, cancellationToken); var dataTask = Task.WhenAll(dcEarningsTask, dasEarningsTask, dataLocksTask, dataLocksTotalTask, dataLocksAlreadyPaid, requiredPaymentsTask, heldBackCompletionAmountsTask, yearToDateAmountsTask); var waitTask = Task.Delay(TimeSpan.FromSeconds(270), cancellationToken); Task.WaitAny(dataTask, waitTask); cancellationToken.ThrowIfCancellationRequested(); if (!dataTask.IsCompleted) { throw new InvalidOperationException($"Took too long to get data for the submission metrics. Ukprn: {ukprn}, job: {jobId}, Collection period: {collectionPeriod}"); } var dataDuration = stopwatch.ElapsedMilliseconds; logger.LogDebug($"finished getting data from databases for job: {jobId}, ukprn: {ukprn}. Took: {dataDuration}ms."); submissionSummary.AddEarnings(dcEarningsTask.Result, dasEarningsTask.Result); submissionSummary.AddDataLockTypeCounts(dataLocksTotalTask.Result, dataLocksTask.Result, dataLocksAlreadyPaid.Result); submissionSummary.AddRequiredPayments(requiredPaymentsTask.Result); submissionSummary.AddHeldBackCompletionPayments(heldBackCompletionAmountsTask.Result); submissionSummary.AddYearToDatePaymentTotals(yearToDateAmountsTask.Result); var metrics = submissionSummary.GetMetrics(); await submissionRepository.SaveSubmissionMetrics(metrics, cancellationToken); stopwatch.Stop(); SendMetricsTelemetry(metrics, stopwatch.ElapsedMilliseconds); logger.LogInfo($"Finished building metrics for submission job: {jobId}, provider: {ukprn}, Academic year: {academicYear}, Collection period: {collectionPeriod}. Took: {stopwatch.ElapsedMilliseconds}ms"); } catch (Exception e) { logger.LogWarning($"Error building the submission metrics report for job: {jobId}, ukprn: {ukprn}. Error: {e}"); throw; } }
public async Task BuildMetrics(long jobId, short academicYear, byte collectionPeriod, CancellationToken cancellationToken) { try { logger.LogDebug($"Building period end metrics for {academicYear}, {collectionPeriod} using job id {jobId}"); var stopwatch = Stopwatch.StartNew(); var dcDataContext = dcMetricsDataContextFactory.CreateContext(academicYear); var dcEarningsTask = dcDataContext.GetEarnings(academicYear, collectionPeriod, cancellationToken); var transactionTypesTask = periodEndMetricsRepository.GetTransactionTypesByContractType(academicYear, collectionPeriod, cancellationToken); var fundingSourceTask = periodEndMetricsRepository.GetFundingSourceAmountsByContractType(academicYear, collectionPeriod, cancellationToken); var currentPaymentTotals = periodEndMetricsRepository.GetYearToDatePayments(academicYear, collectionPeriod, cancellationToken); var dataLockedEarningsTask = periodEndMetricsRepository.GetDataLockedEarningsTotals(academicYear, collectionPeriod, cancellationToken); var dataLockedAlreadyPaidTask = periodEndMetricsRepository.GetAlreadyPaidDataLockedEarnings(academicYear, collectionPeriod, cancellationToken); var heldBackCompletionAmountsTask = periodEndMetricsRepository.GetHeldBackCompletionPaymentsTotals(academicYear, collectionPeriod, cancellationToken); var dataTask = Task.WhenAll( dcEarningsTask, transactionTypesTask, fundingSourceTask, currentPaymentTotals, dataLockedEarningsTask, dataLockedAlreadyPaidTask, heldBackCompletionAmountsTask); var waitTask = Task.Delay(TimeSpan.FromSeconds(270), cancellationToken); Task.WaitAny(dataTask, waitTask); cancellationToken.ThrowIfCancellationRequested(); if (!dataTask.IsCompleted) { throw new InvalidOperationException($"Took too long to get data for the period end metrics. job: {jobId}, Collection period: {collectionPeriod}, Academic Year: {academicYear}"); } var providerSummaries = new List <ProviderPeriodEndSummaryModel>(); var providersFromPayments = currentPaymentTotals.Result.Select(x => x.Ukprn).Distinct(); var providersFromEarnings = dcEarningsTask.Result.Select(x => x.Ukprn).Distinct(); var distinctProviderUkprns = providersFromEarnings.Union(providersFromPayments); var periodEndSummary = periodEndSummaryFactory.CreatePeriodEndSummary(jobId, collectionPeriod, academicYear); foreach (var ukprn in distinctProviderUkprns) { var providerSummary = periodEndSummaryFactory.CreatePeriodEndProviderSummary(ukprn, jobId, collectionPeriod, academicYear); providerSummary.AddDcEarnings(dcEarningsTask.Result.Where(x => x.Ukprn == ukprn)); providerSummary.AddTransactionTypes(transactionTypesTask.Result.Where(x => x.Ukprn == ukprn)); providerSummary.AddFundingSourceAmounts(fundingSourceTask.Result.Where(x => x.Ukprn == ukprn)); providerSummary.AddPaymentsYearToDate(currentPaymentTotals.Result.FirstOrDefault(x => x.Ukprn == ukprn) ?? new ProviderContractTypeAmounts()); providerSummary.AddDataLockedEarnings(dataLockedEarningsTask.Result.FirstOrDefault(x => x.Ukprn == ukprn)?.TotalAmount ?? 0m); providerSummary.AddDataLockedAlreadyPaid(dataLockedAlreadyPaidTask.Result.FirstOrDefault(x => x.Ukprn == ukprn)?.TotalAmount ?? 0m); providerSummary.AddHeldBackCompletionPayments(heldBackCompletionAmountsTask.Result.FirstOrDefault(x => x.Ukprn == ukprn) ?? new ProviderContractTypeAmounts()); var providerSummaryModel = providerSummary.GetMetrics(); providerSummaries.Add(providerSummaryModel); } periodEndSummary.AddProviderSummaries(providerSummaries); var overallPeriodEndSummary = periodEndSummary.GetMetrics(); stopwatch.Stop(); var dataDuration = stopwatch.ElapsedMilliseconds; await periodEndMetricsRepository.SaveProviderSummaries(providerSummaries, overallPeriodEndSummary, cancellationToken); SendSummaryMetricsTelemetry(overallPeriodEndSummary, stopwatch.ElapsedMilliseconds); SendAllProviderMetricsTelemetry(providerSummaries, overallPeriodEndSummary); logger.LogInfo($"Finished building period end metrics for {academicYear}, {collectionPeriod} using job id {jobId}, DataDuration: {dataDuration} milliseconds"); } catch (Exception e) { logger.LogWarning($"Error building period end metrics for {academicYear}, {collectionPeriod} using job id {jobId}. Error: {e}"); throw; } }
private async Task <T> ExecuteDcMetricsQuery <T>(short academicYear, Func <IDcMetricsDataContext, Task <T> > query) { var context = dcMetricsDataContextFactory.CreateContext(academicYear); return(await query(context)); }