fix: Value must be greater than zero exception in Polly CircuitBreaker (#836)

when Only TimeoutValue was set in QoSOptions
This commit is contained in:
Weidaicheng 2019-03-24 05:12:21 +08:00 committed by Thiago Loureiro
parent c5433fcf66
commit bd058c22ca
3 changed files with 41 additions and 28 deletions

View File

@ -1,3 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Polly;
using Polly.CircuitBreaker; using Polly.CircuitBreaker;
using Polly.Timeout; using Polly.Timeout;
@ -5,13 +8,16 @@ namespace Ocelot.Provider.Polly
{ {
public class CircuitBreaker public class CircuitBreaker
{ {
public CircuitBreaker(CircuitBreakerPolicy circuitBreakerPolicy, TimeoutPolicy timeoutPolicy) private readonly List<IAsyncPolicy> _policies = new List<IAsyncPolicy>();
public CircuitBreaker(params IAsyncPolicy[] policies)
{ {
CircuitBreakerPolicy = circuitBreakerPolicy; foreach (var policy in policies.Where(p => p != null))
TimeoutPolicy = timeoutPolicy; {
this._policies.Add(policy);
}
} }
public CircuitBreakerPolicy CircuitBreakerPolicy { get; private set; } public IAsyncPolicy[] Policies => this._policies.ToArray();
public TimeoutPolicy TimeoutPolicy { get; private set; }
} }
} }

View File

@ -25,7 +25,7 @@ namespace Ocelot.Provider.Polly
try try
{ {
return await Policy return await Policy
.WrapAsync(_qoSProvider.CircuitBreaker.CircuitBreakerPolicy, _qoSProvider.CircuitBreaker.TimeoutPolicy) .WrapAsync(_qoSProvider.CircuitBreaker.Policies)
.ExecuteAsync(() => base.SendAsync(request,cancellationToken)); .ExecuteAsync(() => base.SendAsync(request,cancellationToken));
} }
catch (BrokenCircuitException ex) catch (BrokenCircuitException ex)

View File

@ -22,27 +22,34 @@ namespace Ocelot.Provider.Polly
_timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(reRoute.QosOptions.TimeoutValue), strategy); _timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(reRoute.QosOptions.TimeoutValue), strategy);
_circuitBreakerPolicy = Policy if (reRoute.QosOptions.ExceptionsAllowedBeforeBreaking > 0)
.Handle<HttpRequestException>() {
.Or<TimeoutRejectedException>() _circuitBreakerPolicy = Policy
.Or<TimeoutException>() .Handle<HttpRequestException>()
.CircuitBreakerAsync( .Or<TimeoutRejectedException>()
exceptionsAllowedBeforeBreaking: reRoute.QosOptions.ExceptionsAllowedBeforeBreaking, .Or<TimeoutException>()
durationOfBreak: TimeSpan.FromMilliseconds(reRoute.QosOptions.DurationOfBreak), .CircuitBreakerAsync(
onBreak: (ex, breakDelay) => exceptionsAllowedBeforeBreaking: reRoute.QosOptions.ExceptionsAllowedBeforeBreaking,
{ durationOfBreak: TimeSpan.FromMilliseconds(reRoute.QosOptions.DurationOfBreak),
_logger.LogError( onBreak: (ex, breakDelay) =>
".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex); {
}, _logger.LogError(
onReset: () => ".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex);
{ },
_logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."); onReset: () =>
}, {
onHalfOpen: () => _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again.");
{ },
_logger.LogDebug(".Breaker logging: Half-open; next call is a trial."); onHalfOpen: () =>
} {
); _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.");
}
);
}
else
{
_circuitBreakerPolicy = null;
}
CircuitBreaker = new CircuitBreaker(_circuitBreakerPolicy, _timeoutPolicy); CircuitBreaker = new CircuitBreaker(_circuitBreakerPolicy, _timeoutPolicy);
} }