예제 #1
0
        public PrimeController(
            IMapper mapper,
            IMediator mediator,
            ILinksService linksService,
            ILoggingManager loggingManager,
            PolicyConfiguration policyConfiguration)
        {
            _mapper              = mapper;
            _mediator            = mediator;
            _linksService        = linksService;
            _loggingManager      = loggingManager;
            _policyConfiguration = policyConfiguration;

            _circuitBreakerPolicy = Policy
                                    .Handle <TaskCanceledException>()
                                    .CircuitBreakerAsync(policyConfiguration.CircuitBreakerAllowedExceptions, TimeSpan.FromMinutes(_policyConfiguration.CircuitBreakerShutdownDurationInMinutes),
                                                         (ex, t) =>
            {
                _loggingManager.LogFatal("Circuit broken!");
            },
                                                         () =>
            {
                _loggingManager.LogInformation("Circuit Reset!");
            });
        }
예제 #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);
        }