Exemplo n.º 1
0
        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()));
        }
Exemplo n.º 2
0
        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);
        }