public async Task <Result <Guid> > Handle(StartImportNewPollingStations request, CancellationToken cancellationToken) { Guid jobId = Guid.NewGuid(); return(await _importJobsRepository.HasImportJobInProgress() .Ensure(result => result == false, "Cannot start an upload job while an upload is in progress") .Tap(() => _importedPollingStationsRepository.CleanPreviouslyImportedData()) .Bind(_ => _excelParser.ParsePollingStations(request.File)) .Tap(ps => _importedPollingStationsRepository.InsertPollingStations(jobId, ps)) .Tap(() => _importJobsRepository.InsertInJobTable(jobId, request.File)) .Bind(_ => _backgroundJobsQueue.QueueBackgroundWorkItem(jobId)) .Finally(r => r.IsSuccess ? Result.Success(jobId) : Result.Failure <Guid>(r.Error))); }
private async Task BackgroundProcessing(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { var jobId = await _jobsQueue.DequeueAsync(stoppingToken); using (var scope = _serviceScopeFactory.CreateScope()) { var importJobsRepository = scope.ServiceProvider.GetService <IImportJobsRepository>(); var importedPollingStationsRepository = scope.ServiceProvider.GetService <IImportedPollingStationsRepository>(); var locationSearchService = scope.ServiceProvider.GetService <IAddressLocationSearchService>(); try { var jobStatusResult = await importJobsRepository.GetImportJobStatus(jobId); if (jobStatusResult.IsFailure) { continue; } var jobStatus = jobStatusResult.Value.Status; if (jobStatus == JobStatus.Canceled || jobStatus == JobStatus.Finished) { continue; } var query = new ImportedPollingStationsQuery { ResolvedAddressStatus = ResolvedAddressStatusType.NotProcessed }; var defaultPagination = new PaginationQuery(); var pollingStations = await importedPollingStationsRepository.GetImportedPollingStationsAsync(jobId, query, defaultPagination); if (pollingStations.IsFailure) { continue; } if (pollingStations.Value.RowCount == 0) { await importJobsRepository.UpdateJobStatus(jobId, JobStatus.Finished); continue; } await importJobsRepository.UpdateJobStatus(jobId, JobStatus.Started); foreach (var ps in pollingStations.Value.Results) { var locationSearchResult = await locationSearchService.FindCoordinates(ps.County, ps.Address); ps.ResolvedAddressStatus = locationSearchResult.OperationStatus; ps.Latitude = locationSearchResult.Latitude; ps.Longitude = locationSearchResult.Longitude; ps.FailMessage = locationSearchResult.ErrorMessage; await importedPollingStationsRepository.UpdateImportedPollingStation(jobId, ps); } _jobsQueue.QueueBackgroundWorkItem(jobId); } catch (Exception ex) { _logger.LogError(ex, "Error occurred executing {WorkItem}.", nameof(jobId)); } } } }