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()); }
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); }
private IBotPolicy CreatePolicy(CircuitBreakerConfiguration conf, DefaultCircuitBreakerStrategyConfiguration strConf) => new BotPolicy(config => config .Configure(botconfig => botconfig .CircuitBreaker(conf, strConf)));
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)); }