/// <summary> /// Generates the circuit breaker policy for a service. /// </summary> /// <param name="serviceInfo">The service to generate the circuit breaker policy for</param> /// <returns>The circuit policy</returns> protected AsyncPolicyWrap <ServiceResponse> GetCircuitBreakerPolicy(CalledServiceInfo serviceInfo) { return(CircuitBreakerPolicies.GetOrAdd(serviceInfo.CacheKey, _ => { AsyncTimeoutPolicy timeoutPolicy = Policy .TimeoutAsync( serviceInfo.Timeout, TimeoutStrategy.Pessimistic ); AsyncCircuitBreakerPolicy <ServiceResponse> circuitBreakerPolicy = Policy <ServiceResponse> .Handle <TimeoutRejectedException>() .OrResult(resultPredicate: serviceResponse => serviceResponse.Status == ServiceResponseStatus.Error) .CircuitBreakerAsync( handledEventsAllowedBeforeBreaking: serviceInfo.CircuitBreakerInfo.ExceptionCount, durationOfBreak: serviceInfo.CircuitBreakerInfo.BreakDuration, onBreak: (__, ___) => { Log.Warning("Service ({ServiceName}) has reached its threshold for the circuit breaker and the circuit has been opened", serviceInfo.Name); }, onReset: () => { Log.Warning("Service ({ServiceName}) has been determined to be back up, circuit closed again", serviceInfo.Name); } ); AsyncPolicyWrap <ServiceResponse> circuitBreakerWrappingTimeout = circuitBreakerPolicy .WrapAsync(timeoutPolicy); AsyncFallbackPolicy <ServiceResponse> timeoutFallbackPolicy = Policy <ServiceResponse> .Handle <TimeoutRejectedException>() .FallbackAsync( cancellationToken => { return Task.FromResult(new ServiceResponse { Status = ServiceResponseStatus.Timeout, ServiceId = serviceInfo.Id }); }); AsyncPolicyWrap <ServiceResponse> timeoutFallbackPolicyWrappingCircuitBreaker = timeoutFallbackPolicy .WrapAsync(circuitBreakerWrappingTimeout); AsyncFallbackPolicy <ServiceResponse> exceptionFallbackPolicy = Policy <ServiceResponse> .Handle <Exception>() .FallbackAsync( cancellationToken => { return Task.FromResult(new ServiceResponse { Status = ServiceResponseStatus.Error, ServiceId = serviceInfo.Id }); }); AsyncPolicyWrap <ServiceResponse> exceptionFallbackPolicyWrappingTimeoutFallback = exceptionFallbackPolicy .WrapAsync(timeoutFallbackPolicyWrappingCircuitBreaker); AsyncPolicyWrap <ServiceResponse> policy = exceptionFallbackPolicyWrappingTimeoutFallback; return policy; })); }
/// <summary> /// Policy Resiliance Strategy /// </summary> /// <returns></returns> public AsyncPolicy GetResillianceStrategy() { return(_circuitBreakerPolicy.WrapAsync(_retryPolicy.WrapAsync(_bulkheadPolicy))); }