/// <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;
            }));
        }
예제 #2
0
 /// <summary>
 /// Policy Resiliance Strategy
 /// </summary>
 /// <returns></returns>
 public AsyncPolicy GetResillianceStrategy()
 {
     return(_circuitBreakerPolicy.WrapAsync(_retryPolicy.WrapAsync(_bulkheadPolicy)));
 }