public async void Wrapping_two_generic_policies_by_static_syntax_and_executing_should_wrap_outer_then_inner_around_delegate() { RetryPolicy <ResultPrimitive> retry = Policy.HandleResult(ResultPrimitive.Fault).RetryAsync(1); // Two tries in total: first try, plus one retry. CircuitBreakerPolicy <ResultPrimitive> breaker = Policy.HandleResult(ResultPrimitive.Fault).CircuitBreakerAsync(2, TimeSpan.MaxValue); var retryWrappingBreaker = Policy.WrapAsync(retry, breaker); var breakerWrappingRetry = Policy.WrapAsync(breaker, retry); // When the retry wraps the breaker, the retry (being outer) should cause the call to be put through the breaker twice - causing the breaker to break. breaker.Reset(); (await retryWrappingBreaker.RaiseResultSequenceAsync(ResultPrimitive.Fault, ResultPrimitive.Fault).ConfigureAwait(false)) .Should().Be(ResultPrimitive.Fault); breaker.CircuitState.Should().Be(CircuitState.Open); // When the breaker wraps the retry, the retry (being inner) should retry twice before throwing the exception back on the breaker - the exception only hits the breaker once - so the breaker should not break. breaker.Reset(); (await breakerWrappingRetry.RaiseResultSequenceAsync(ResultPrimitive.Fault, ResultPrimitive.Fault).ConfigureAwait(false)) .Should().Be(ResultPrimitive.Fault); breaker.CircuitState.Should().Be(CircuitState.Closed); }
public void Wrapping_two_policies_by_static_syntax_and_executing_should_wrap_outer_then_inner_around_delegate() { RetryPolicy retry = Policy.Handle <Exception>().RetryAsync(1); // Two tries in total: first try, plus one retry. CircuitBreakerPolicy breaker = Policy.Handle <Exception>().CircuitBreakerAsync(2, TimeSpan.MaxValue); PolicyWrap retryWrappingBreaker = Policy.WrapAsync(retry, breaker); PolicyWrap breakerWrappingRetry = Policy.WrapAsync(breaker, retry); // When the retry wraps the breaker, the retry (being outer) should cause the call to be put through the breaker twice - causing the breaker to break. breaker.Reset(); retryWrappingBreaker.Awaiting(async x => await x.RaiseExceptionAsync <DivideByZeroException>(2)) .ShouldThrow <DivideByZeroException>(); breaker.CircuitState.Should().Be(CircuitState.Open); // When the breaker wraps the retry, the retry (being inner) should retry twice before throwing the exception back on the breaker - the exception only hits the breaker once - so the breaker should not break. breaker.Reset(); breakerWrappingRetry.Awaiting(async x => await x.RaiseExceptionAsync <DivideByZeroException>(2)) .ShouldThrow <DivideByZeroException>(); breaker.CircuitState.Should().Be(CircuitState.Closed); }
static void CircuitBreaker() { Action <Exception, TimeSpan, Context> onBreak = (exception, timespan, context) => { Console.WriteLine("onBreak Running : " + exception.Message); }; Action <Context> onReset = context => { Console.WriteLine("Job Back to normal"); }; CircuitBreakerPolicy breaker = Policy .Handle <AggregateException>() .CircuitBreaker(3, TimeSpan.FromSeconds(10), onBreak, onReset); // Monitor the circuit state, for example for health reporting. CircuitState state = breaker.CircuitState; ISyncPolicy policy = Policy.Handle <ArgumentException>() .Retry(3, (ex, retryCount, context) => { Console.WriteLine($"Runing fallback,Exception :{ex.Message},RetryCount:{retryCount}"); }); while (true) { try { var policyWrap = Policy.Wrap(policy, breaker); // (wraps the policies around any executed delegate: fallback outermost ... bulkhead innermost) policyWrap.Execute(() => { Console.WriteLine("Job Start"); if (DateTime.Now.Second % 3 == 0) { throw new ArgumentException("Hello Polly!"); } }); } catch (Exception ex) { // 手动打开熔断器,阻止执行 breaker.Isolate(); } Thread.Sleep(1000); // 恢复操作,启动执行 breaker.Reset(); } }
static async Task TestCircuitBreaker() { while (true) { Thread.Sleep(1000); string testUrl = ""; switch (_circuitBreakerPolicy.CircuitState) { case CircuitState.Closed: // Circuit fermé, on envoie direct une URL d'échec testUrl = "http://localhost:9000/api/test/failure/"; Console.WriteLine("CircuitState = Closed, try 'failure' request ..."); break; case CircuitState.HalfOpen: // Circuit semi-ouvert, on envoie une url qui fonctionne pour le refermer testUrl = "http://localhost:9000/api/test/retries/"; Console.WriteLine("CircuitState = HalfOpen, try 'retries' request ..."); break; case CircuitState.Isolated: // Circuit isolé, on le referme et on continue _circuitBreakerPolicy.Reset(); testUrl = "http://localhost:9000/api/test/retries/"; Console.WriteLine("CircuitState = Isolated, try 'retries' request ..."); break; case CircuitState.Open: // Circuit ouvert : même pas la peine d'essayer Console.WriteLine("CircuitState = Open, waiting for Closed state ..."); Console.WriteLine("(Remaining time = " + GetCircuitBreakerRemainingTime() + " sec.)"); return; } Policy retryPolicy = Policy.Handle <HttpRequestException>().RetryAsync(3, (ex, timeSpan) => { Console.WriteLine($"Retry Policy Exception: {ex.Message}"); }); await retryPolicy.ExecuteAsync(() => _circuitBreakerPolicy.ExecuteAsync(async() => { var httpClient = new HttpClient(); var response = await httpClient.GetAsync(testUrl); response.EnsureSuccessStatusCode(); Console.WriteLine(response.StatusCode); })); } }
public void Should_close_circuit_again_on_reset_after_manual_override() { var time = 1.January(2000); SystemClock.UtcNow = () => time; var durationOfBreak = TimeSpan.FromMinutes(1); CircuitBreakerPolicy breaker = Policy .Handle <DivideByZeroException>() .CircuitBreaker(2, durationOfBreak); breaker.CircuitState.Should().Be(CircuitState.Closed); breaker.Isolate(); breaker.CircuitState.Should().Be(CircuitState.Isolated); breaker.Invoking(x => x.Execute(() => { })) .ShouldThrow <IsolatedCircuitException>(); breaker.Reset(); breaker.CircuitState.Should().Be(CircuitState.Closed); breaker.Invoking(x => x.Execute(() => { })).ShouldNotThrow(); }
public void Should_set_LastHandledResult_and_LastException_to_default_on_circuit_reset() { CircuitBreakerPolicy <ResultPrimitive> breaker = Policy .Handle <DivideByZeroException>() .OrResult(ResultPrimitive.Fault) .CircuitBreaker(2, TimeSpan.FromMinutes(1)); breaker.Invoking(b => b.RaiseResultAndOrExceptionSequence(new DivideByZeroException())) .ShouldThrow <DivideByZeroException>(); breaker.RaiseResultSequence(ResultPrimitive.Fault) .Should().Be(ResultPrimitive.Fault); breaker.CircuitState.Should().Be(CircuitState.Open); breaker.LastHandledResult.Should().Be(ResultPrimitive.Fault); breaker.LastException.Should().BeNull(); breaker.Reset(); breaker.LastHandledResult.Should().Be(default(ResultPrimitive)); breaker.LastException.Should().BeNull(); }