Skip to content

Commit

Permalink
#2080 Adds parameters (in this case those of Polly V8) to fine-tune c…
Browse files Browse the repository at this point in the history
…ircuit-breaker behavior
  • Loading branch information
RaynaldM committed May 29, 2024
1 parent cc8f5c5 commit 3c125a2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public ResiliencePipeline<HttpResponseMessage> GetResiliencePipeline(DownstreamR
var options = route.QosOptions;

// Check if we need pipeline at all before calling GetOrAddPipeline
if (options is null ||
if (options is null || options.UseQos == false ||
(options.ExceptionsAllowedBeforeBreaking == 0 && options.TimeoutValue is int.MaxValue))
{
return null; // shortcut > no qos
Expand All @@ -48,6 +48,8 @@ private void PollyResiliencePipelineWrapperFactory(ResiliencePipelineBuilder<Htt
{
var options = route.QosOptions;

if(!options.UseQos) return; // shortcut > no qos

// Add TimeoutStrategy if TimeoutValue is not int.MaxValue and greater than 0
if (options.TimeoutValue != int.MaxValue && options.TimeoutValue > 0)
{
Expand All @@ -64,8 +66,8 @@ private void PollyResiliencePipelineWrapperFactory(ResiliencePipelineBuilder<Htt

var circuitBreakerStrategyOptions = new CircuitBreakerStrategyOptions<HttpResponseMessage>
{
FailureRatio = 0.8,
SamplingDuration = TimeSpan.FromSeconds(10),
FailureRatio = options.FailureRatio,
SamplingDuration = TimeSpan.FromSeconds(options.SamplingDuration),
MinimumThroughput = options.ExceptionsAllowedBeforeBreaking,
BreakDuration = TimeSpan.FromMilliseconds(options.DurationOfBreak),
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
Expand Down
48 changes: 47 additions & 1 deletion src/Ocelot/Configuration/QoSOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public QoSOptions(FileQoSOptions from)
public QoSOptions(
int exceptionsAllowedBeforeBreaking,
int durationOfBreak,
int timeoutValue,
int timeoutValue,
string key)
{
DurationOfBreak = durationOfBreak;
Expand All @@ -32,6 +32,36 @@ public QoSOptions(
TimeoutValue = timeoutValue;
}

public QoSOptions(
int exceptionsAllowedBeforeBreaking,
int durationOfBreak,
double failureRatio,
int timeoutValue,
string key)
{
DurationOfBreak = durationOfBreak;
ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
Key = key;
TimeoutValue = timeoutValue;
FailureRatio = failureRatio;
}

public QoSOptions(
int exceptionsAllowedBeforeBreaking,
int durationOfBreak,
double failureRatio,
int samplingDuration,
int timeoutValue,
string key)
{
DurationOfBreak = durationOfBreak;
ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
Key = key;
TimeoutValue = timeoutValue;
FailureRatio = failureRatio;
SamplingDuration = samplingDuration;
}

/// <summary>
/// How long the circuit should stay open before resetting in milliseconds.
/// </summary>
Expand All @@ -54,6 +84,22 @@ public QoSOptions(
/// </value>
public int ExceptionsAllowedBeforeBreaking { get; }

/// <summary>
/// The failure-success ratio that will cause the circuit to break/open.
/// </summary>
/// <value>
/// An <see cref="double"/> 0.8 means 80% failed of all sampled executions.
/// </value>
public double FailureRatio { get; } = .8;

/// <summary>
/// The time period over which the failure-success ratio is calculated (in seconds).
/// </summary>
/// <value>
/// An <see cref="int"/> Time period in seconds, 10 means 10 seconds.
/// </value>
public int SamplingDuration { get; } = 10;

public string Key { get; }

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion test/Ocelot.AcceptanceTests/PollyQoSTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public override void Dispose()
public void Should_not_timeout()
{
var port = PortFinder.GetRandomPort();
var configuration = FileConfigurationFactory(port, new QoSOptions(10, 500, 1000, null), HttpMethods.Post);
var configuration = FileConfigurationFactory(port, new QoSOptions(10, 500,.5,5, 1000, null), HttpMethods.Post);

this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200, string.Empty, 10))
.And(x => GivenThereIsAConfiguration(configuration))
Expand Down

0 comments on commit 3c125a2

Please sign in to comment.