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!"); }); }
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); }