diff --git a/src/Ocelot.Provider.Polly/PollyQoSResiliencePipelineProvider.cs b/src/Ocelot.Provider.Polly/PollyQoSResiliencePipelineProvider.cs index be2df16b3..6486589d1 100644 --- a/src/Ocelot.Provider.Polly/PollyQoSResiliencePipelineProvider.cs +++ b/src/Ocelot.Provider.Polly/PollyQoSResiliencePipelineProvider.cs @@ -32,7 +32,7 @@ public ResiliencePipeline 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 @@ -48,6 +48,8 @@ private void PollyResiliencePipelineWrapperFactory(ResiliencePipelineBuilder no qos + // Add TimeoutStrategy if TimeoutValue is not int.MaxValue and greater than 0 if (options.TimeoutValue != int.MaxValue && options.TimeoutValue > 0) { @@ -64,8 +66,8 @@ private void PollyResiliencePipelineWrapperFactory(ResiliencePipelineBuilder { - 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() diff --git a/src/Ocelot/Configuration/QoSOptions.cs b/src/Ocelot/Configuration/QoSOptions.cs index e1897bc58..b601ef91d 100644 --- a/src/Ocelot/Configuration/QoSOptions.cs +++ b/src/Ocelot/Configuration/QoSOptions.cs @@ -23,7 +23,7 @@ public QoSOptions(FileQoSOptions from) public QoSOptions( int exceptionsAllowedBeforeBreaking, int durationOfBreak, - int timeoutValue, + int timeoutValue, string key) { DurationOfBreak = durationOfBreak; @@ -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; + } + /// /// How long the circuit should stay open before resetting in milliseconds. /// @@ -54,6 +84,22 @@ public QoSOptions( /// public int ExceptionsAllowedBeforeBreaking { get; } + /// + /// The failure-success ratio that will cause the circuit to break/open. + /// + /// + /// An 0.8 means 80% failed of all sampled executions. + /// + public double FailureRatio { get; } = .8; + + /// + /// The time period over which the failure-success ratio is calculated (in seconds). + /// + /// + /// An Time period in seconds, 10 means 10 seconds. + /// + public int SamplingDuration { get; } = 10; + public string Key { get; } /// diff --git a/test/Ocelot.AcceptanceTests/PollyQoSTests.cs b/test/Ocelot.AcceptanceTests/PollyQoSTests.cs index 597731755..dc75b3957 100644 --- a/test/Ocelot.AcceptanceTests/PollyQoSTests.cs +++ b/test/Ocelot.AcceptanceTests/PollyQoSTests.cs @@ -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))