예제 #1
0
        public async Task <FindNextPrimeCommandResult> Handle(FindNextPrimeCommand request, CancellationToken cancellationToken)
        {
            var primeLink = await _primeLinkRepository.GetPrimeLinkbyNumberAsync(request.Number);

            var result = new FindNextPrimeCommandResult();

            if (primeLink == null ||
                primeLink.CalculationStatus == CalculationStatus.Failed)
            {
                try
                {
                    if (primeLink == null)
                    {
                        await _primeLinkRepository.StartNewPrimeLinkCalculationAsync(request.Number);
                    }

                    var scienceRequestData = new PrimeCalculationRequest
                    {
                        Number = 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
                    });

                    result.NextPrime = scienceResult.NextPrime;
                }
                catch (TaskCanceledException taskCanceledException)
                {
                    _loggingManager.LogFatal(taskCanceledException.Message);

                    await _primeLinkRepository.UpdatePrimeLinkAsync(new Models.PrimeLinkModel
                    {
                        Number            = request.Number,
                        CalculationStatus = CalculationStatus.Failed,
                    });

                    throw;
                }
                catch (Exception exception)
                {
                    _loggingManager.LogError(exception.Message);

                    await _primeLinkRepository.UpdatePrimeLinkAsync(new Models.PrimeLinkModel
                    {
                        Number            = request.Number,
                        CalculationStatus = CalculationStatus.Unknown,
                    });

                    throw;
                }
            }
            else if (primeLink.CalculationStatus == CalculationStatus.Done)
            {
                result.NextPrime = primeLink.NextPrime;
            }
            else if (primeLink.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 _primeLinkRepository.GetPrimeLinkbyNumberAsync(request.Number);

                    if (currentState.CalculationStatus == CalculationStatus.Done)
                    {
                        result.NextPrime = currentState.NextPrime;
                        break;
                    }
                }
            }
            else
            {
                throw new Exception("Something went wrong please contact support.");
            }

            return(result);
        }
        public async Task <PrimeLinkModel> Handle(GetPrimeLinkByNumberQuery request, CancellationToken cancellationToken)
        {
            var primeLink = await _primeLinkRepository.GetPrimeLinkbyNumberAsync(request.Number);

            return(primeLink ?? _mapper.Map <PrimeLinkModel>(primeLink));
        }