public void When_Canary_Fails_Circuit_Opens()
        {
            var config = new CircuitBreakerConfiguration
            {
                VolumeThreshold = 1,
                SleepWindow     = TimeSpan.FromMilliseconds(50)
            };

            var circuitBreaker = new CircuitBreaker(config);

            circuitBreaker.MarkFailure();
            Thread.Sleep(config.SleepWindow.Add(TimeSpan.FromMilliseconds(1)));
            circuitBreaker.Track();

            Assert.Equal(CircuitBreakerState.HalfOpen, circuitBreaker.State);
            Assert.False(circuitBreaker.AllowsRequest());

            circuitBreaker.MarkFailure();
            Assert.Equal(CircuitBreakerState.Open, circuitBreaker.State);
            Assert.False(circuitBreaker.AllowsRequest());

            Thread.Sleep(config.SleepWindow.Add(TimeSpan.FromMilliseconds(1)));
            Assert.Equal(CircuitBreakerState.Open, circuitBreaker.State);
            Assert.True(circuitBreaker.AllowsRequest());
        }
        /// <summary>
        /// Adds a circuit breaker bot to a <see cref="IBotPolicy"/> with the given configuration.
        /// </summary>
        /// <param name="builder">The policy builder.</param>
        /// <param name="configuration">The bots configuraton.</param>
        /// <param name="strategyConfiguration">The circuit breakers configuraton.</param>
        /// <returns>The policy builder.</returns>
        /// <example>
        /// <code>
        /// builder.CircuitBreaker(new CircuitBreakerConfiguration()
        ///         .BrakeWhenExceptionOccurs(exception => exception is HttpRequestException)
        ///         .OnClosed(() => onClosedAction())
        ///         .OnHalfOpen(() => onHalfOpenAction())
        ///         .OnOpen(openDuration => onOpenAction(openDuration)),
        ///             new DefaultCircuitBreakerStrategyConfiguration()
        ///                 .DurationOfOpen(TimeSpan.FromSeconds(15))
        ///                 .FailureThresholdBeforeOpen(5)
        ///                 .SuccessThresholdInHalfOpen(2));
        /// </code>
        /// </example>
        public static IBotPolicyBuilder CircuitBreaker(this IBotPolicyBuilder builder,
                                                       CircuitBreakerConfiguration configuration, DefaultCircuitBreakerStrategyConfiguration strategyConfiguration)
        {
            Shield.EnsureNotNull(configuration, nameof(configuration));
            Shield.EnsureNotNull(strategyConfiguration, nameof(strategyConfiguration));

            return(builder.AddBot((innerBot, config) => new CircuitBreakerBot(innerBot, config,
                                                                              new DefaultCircuitBreakerStrategy(config, strategyConfiguration)), configuration));
        }
        public void When_Volume_Exceeded_Circuit_Opens()
        {
            var config         = new CircuitBreakerConfiguration();
            var circuitBreaker = new CircuitBreaker(config);

            for (var i = 0; i < config.VolumeThreshold - 1; i++)
            {
                circuitBreaker.MarkFailure();
                Assert.Equal(CircuitBreakerState.Closed, circuitBreaker.State);
                Assert.True(circuitBreaker.AllowsRequest());
            }

            circuitBreaker.MarkFailure();
            Assert.False(circuitBreaker.AllowsRequest());
            Assert.Equal(CircuitBreakerState.Open, circuitBreaker.State);
        }
        public void When_State_is_Open_Can_Reset()
        {
            var config = new CircuitBreakerConfiguration
            {
                VolumeThreshold = 1
            };

            var circuitBreaker = new CircuitBreaker(config);

            circuitBreaker.MarkFailure();
            Assert.Equal(CircuitBreakerState.Open, circuitBreaker.State);
            Assert.False(circuitBreaker.AllowsRequest());

            circuitBreaker.Reset();

            Assert.Equal(CircuitBreakerState.Closed, circuitBreaker.State);
            Assert.True(circuitBreaker.AllowsRequest());
        }
        public void When_Window_Is_Expired_State_Is_Reset()
        {
            var config = new CircuitBreakerConfiguration
            {
                RollingWindow = TimeSpan.FromSeconds(10)
            };
            var circuitBreaker = new CircuitBreaker(config);

            for (var i = 0; i < 22; i++)
            {
                circuitBreaker.MarkFailure();
                if (i == 20)
                {
                    Thread.Sleep(config.RollingWindow);
                }
            }
            circuitBreaker.MarkSuccess();
            Assert.True(circuitBreaker.AllowsRequest());
            Assert.Equal(CircuitBreakerState.Closed, circuitBreaker.State);
        }
        public void When_RollingWindow_Completes_State_Is_Closed()
        {
            var config = new CircuitBreakerConfiguration
            {
                VolumeThreshold = 2,
                RollingWindow   = TimeSpan.FromMilliseconds(100)
            };

            var circuitBreaker = new CircuitBreaker(config);

            circuitBreaker.MarkFailure();
            Assert.Equal(CircuitBreakerState.Closed, circuitBreaker.State);
            Assert.True(circuitBreaker.AllowsRequest());

            Thread.Sleep(config.SleepWindow.Add(TimeSpan.FromMilliseconds(1)));

            circuitBreaker.MarkFailure();
            Assert.Equal(CircuitBreakerState.Closed, circuitBreaker.State);
            Assert.True(circuitBreaker.AllowsRequest());
        }
示例#7
0
        public void CircuitBreakerConfiguration_CustomCircuitBreakerConfiguration_LoadsInServiceProvider()
        {
            // Arrange

            var config = new ClusterOptions();

            var expectedCircuitBreakerConfiguration = new CircuitBreakerConfiguration
            {
                Enabled = false
            };

            // Act

            config.CircuitBreakerConfiguration = expectedCircuitBreakerConfiguration;

            // Assert

            var serviceProvider = config.BuildServiceProvider();
            var actualCircuitBreakerConfiguration = serviceProvider.GetService <CircuitBreakerConfiguration>();

            Assert.Equal(expectedCircuitBreakerConfiguration, actualCircuitBreakerConfiguration);
        }
        public static AsyncCircuitBreakerPolicy <HttpResponseMessage> ConfigureCircuitBreakerPolicy(CircuitBreakerConfiguration circuitBreakerConfig)
        {
            AsyncCircuitBreakerPolicy <HttpResponseMessage> circuitBreaker = null;

            if (circuitBreakerConfig != null)
            {
                circuitBreaker = HttpPolicyExtensions.HandleTransientHttpError()
                                 .CircuitBreakerAsync(circuitBreakerConfig.ExceptionsAllowedBeforeBreaking,
                                                      TimeSpan.FromMilliseconds(circuitBreakerConfig.DurationOfBreakMs),
                                                      (result, timespan, context) =>
                {
                    var request = result.Result.RequestMessage;
                    Log.Logger.Warning(
                        $"{context.PolicyKey}: Breaking the circuit for {timespan.TotalSeconds} seconds. {request.Method} {request.RequestUri}");
                }, context => { Log.Logger.Warning($"{context.PolicyKey}: Closing the circuit."); });
            }

            return(circuitBreaker);
        }
示例#9
0
 private IBotPolicy CreatePolicy(CircuitBreakerConfiguration conf, DefaultCircuitBreakerStrategyConfiguration strConf) =>
 new BotPolicy(config => config
               .Configure(botconfig => botconfig
                          .CircuitBreaker(conf, strConf)));
示例#10
0
 internal Money(CircuitBreakerConfiguration configuration)
 => circuitBreaker = new CircuitBreaker <ExchangeCurrencies, ExchangeRates>(
        /// <summary>
        /// Adds a circuit breaker bot with a custom strategy implementation to a <see cref="IBotPolicy"/>.
        /// </summary>
        /// <param name="builder">The policy builder.</param>
        /// <param name="configuraton">The bots configuraton.</param>
        /// <param name="strategyFactory">The custom circuit breaker strategy factory delegate.</param>
        /// <returns>The policy builder.</returns>
        /// <example>
        /// <code>
        /// builder.CircuitBreaker(switcher => new CustomCircuitBreakerStrategy(switcher),
        ///     new CircuitBreakerConfiguration()
        ///         .BrakeWhenExceptionOccurs(exception => exception is HttpRequestException)
        ///         .BrakeWhenResultIs(result => result != OperationResult.Ok)
        ///         .OnClosed(() => onClosedAction())
        ///         .OnHalfOpen(() => onHalfOpenAction())
        ///         .OnOpen(openDuration => onOpenAction(openDuration)));
        /// </code>
        /// </example>
        public static IBotPolicyBuilder <TResult> CustomCircuitBreaker <TResult>(this IBotPolicyBuilder <TResult> builder,
                                                                                 Func <CircuitBreakerConfiguration <TResult>, CircuitBreakerStrategy> strategyFactory, CircuitBreakerConfiguration <TResult> configuraton)
        {
            Shield.EnsureNotNull(configuraton, nameof(configuraton));
            Shield.EnsureNotNull(strategyFactory, nameof(strategyFactory));

            return(builder.AddBot((innerBot, config) => new CircuitBreakerBot <TResult>(innerBot, config, strategyFactory(config)), configuraton));
        }