public Task <Unit> Handle(StartNextPrimeCalculationCommand request, CancellationToken cancellationToken) { var scienceRequestData = new PrimeCalculationRequest { Number = request.Number }; _backgroundTaskQueue.QueueBackgroundWorkItem(async(token, serviceProvider) => { using (var scope = serviceProvider.CreateScope()) { var primeLinkRepository = scope.ServiceProvider.GetRequiredService <IPrimeLinkRepository>(); var primeLink = await primeLinkRepository.GetPrimeLinkbyNumberAsync(request.Number); if (primeLink == null || primeLink.CalculationStatus == CalculationStatus.Failed) { if (primeLink == null) { await primeLinkRepository.StartNewPrimeLinkCalculationAsync(request.Number); } var scienceReply = await UseScienceInterface("FindNextPrime", scienceRequestData.ToByteArray(), cancellationToken); var scienceResult = NextPrimeResponse.Parser.ParseFrom(scienceReply.RawBytes); await primeLinkRepository.UpdatePrimeLinkAsync(new Models.PrimeLinkModel { Number = request.Number, CalculationStatus = CalculationStatus.Done, NextPrime = scienceResult.NextPrime }); } } }); return(Task.FromResult(new Unit())); }
public async Task <CheckNumberIsPrimeCommandResult> Handle(CheckNumberIsPrimeCommand request, CancellationToken cancellationToken) { var calculation = await _calculationRepository.GetCalculationByNumberAsync(request.Number); var result = new CheckNumberIsPrimeCommandResult(); if (calculation == null || calculation.CalculationStatus == CalculationStatus.Failed) { if (calculation == null) { await _calculationRepository.StartNewCalculationAsync(request.Number); } try { var scienceRequestData = new PrimeCalculationRequest { Number = request.Number }; var scienceReply = await UseScienceInterface("NumberIsPrime", scienceRequestData.ToByteArray(), cancellationToken); var scienceResult = NumberIsPrimeResponse.Parser.ParseFrom(scienceReply.RawBytes); await _calculationRepository.UpdateCalculationAsync(new CalculationModel { Number = request.Number, CalculationStatus = CalculationStatus.Done, IsPrime = scienceResult.IsPrime }); result.IsPrime = scienceResult.IsPrime; } catch (TaskCanceledException taskCanceledException) { _loggingManager.LogFatal(taskCanceledException.Message); await _calculationRepository.UpdateCalculationAsync(new CalculationModel { Number = request.Number, CalculationStatus = CalculationStatus.Failed, }); throw; } catch (Exception exception) { _loggingManager.LogError(exception.Message); await _calculationRepository.UpdateCalculationAsync(new CalculationModel { Number = request.Number, CalculationStatus = CalculationStatus.Unknown, }); throw; } } else if (calculation.CalculationStatus == CalculationStatus.Done) { result.IsPrime = calculation.IsPrime; return(result); } else if (calculation.CalculationStatus == CalculationStatus.InProgress) { //TODO: refactor to appsettings //TODO: use polly for timeout policy TimeSpan checkTime = TimeSpan.FromMinutes(0.25); while (true) { await Task.Delay(checkTime, cancellationToken); var currentState = await _calculationRepository.GetCalculationByNumberAsync(request.Number); if (currentState.CalculationStatus == CalculationStatus.Done) { result.IsPrime = currentState.IsPrime; break; } } } else { throw new Exception("Something went wrong please contact support."); } //TODO: check if task is in progress or unknown return(result); }