Skip to content

Commit

Permalink
Drop Outcome and cleanup the options (#1235)
Browse files Browse the repository at this point in the history
  • Loading branch information
martintmk authored May 30, 2023
1 parent 38d3e09 commit 63853e2
Show file tree
Hide file tree
Showing 40 changed files with 153 additions and 569 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void Initialize_Ok()
() =>
{
exceptionCalled = true;
return new Outcome(new InvalidOperationException());
return new Outcome<object>(new InvalidOperationException());
});

provider.CircuitState.Should().Be(CircuitState.HalfOpen);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Polly.Core.Tests.CircuitBreaker.Controller;
public class CircuitStateControllerTests
{
private readonly FakeTimeProvider _timeProvider = new();
private readonly CircuitBreakerStrategyOptions _options = new SimpleCircuitBreakerStrategyOptions();
private readonly CircuitBreakerStrategyOptions<object> _options = new SimpleCircuitBreakerStrategyOptions();
private readonly Mock<CircuitBehavior> _circuitBehavior = new(MockBehavior.Strict);
private readonly Action<IResilienceArguments> _onTelemetry = _ => { };
private DateTimeOffset _utcNow = DateTimeOffset.UtcNow;
Expand Down
67 changes: 0 additions & 67 deletions src/Polly.Core.Tests/Strategy/OutcomeTResultTests.cs

This file was deleted.

60 changes: 38 additions & 22 deletions src/Polly.Core.Tests/Strategy/OutcomeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,62 @@ public class OutcomeTests
[Fact]
public void Ctor_Result_Ok()
{
var outcome = new Outcome(10);

outcome.Result.Should().Be(10);
var outcome = new Outcome<int>(10);
outcome.HasResult.Should().BeTrue();
outcome.Exception.Should().BeNull();
outcome.ExceptionDispatchInfo.Should().BeNull();
outcome.IsVoidResult.Should().BeFalse();
outcome.TryGetResult(out var resultObj).Should().BeTrue();
resultObj.Should().Be(10);
outcome.TryGetResult(out var result).Should().BeTrue();
result.Should().Be(10);
outcome.ToString().Should().Be("10");
outcome.ExceptionDispatchInfo.Should().BeNull();

outcome.AsOutcome().HasResult.Should().BeTrue();
outcome.AsOutcome().Exception.Should().BeNull();
outcome.AsOutcome().IsVoidResult.Should().BeFalse();
outcome.AsOutcome().TryGetResult(out var resultObj).Should().BeTrue();
resultObj.Should().Be(10);
}

[Fact]
public void Ctor_Exception_Ok()
public void Ctor_VoidResult_Ok()
{
var outcome = new Outcome(new InvalidOperationException("Dummy message."));
var outcome = new Outcome<VoidResult>(VoidResult.Instance);
outcome.HasResult.Should().BeTrue();
outcome.Exception.Should().BeNull();
outcome.IsVoidResult.Should().BeTrue();
outcome.TryGetResult(out var result).Should().BeFalse();
outcome.Result.Should().Be(VoidResult.Instance);
outcome.ToString().Should().Be("void");

outcome.AsOutcome().HasResult.Should().BeTrue();
outcome.AsOutcome().Exception.Should().BeNull();
outcome.AsOutcome().IsVoidResult.Should().BeTrue();
outcome.AsOutcome().TryGetResult(out _).Should().BeFalse();
outcome.AsOutcome().Result.Should().Be(VoidResult.Instance);
}

[Fact]
public void Ctor_Exception_Ok()
{
var outcome = new Outcome<VoidResult>(new InvalidOperationException("Dummy message."));
outcome.HasResult.Should().BeFalse();
outcome.Exception.Should().NotBeNull();
outcome.ExceptionDispatchInfo.Should().NotBeNull();
outcome.IsVoidResult.Should().BeFalse();
outcome.TryGetResult(out _).Should().BeFalse();
outcome.TryGetResult(out var result).Should().BeFalse();
outcome.ToString().Should().Be("Dummy message.");
outcome.ExceptionDispatchInfo.Should().NotBeNull();

outcome.AsOutcome().HasResult.Should().BeFalse();
outcome.AsOutcome().Exception.Should().NotBeNull();
outcome.AsOutcome().IsVoidResult.Should().BeFalse();
outcome.AsOutcome().TryGetResult(out _).Should().BeFalse();
outcome.AsOutcome().ExceptionDispatchInfo.Should().Be(outcome.ExceptionDispatchInfo);
}

[Fact]
public void ToString_NullResult_ShouldBeEmpty()
{
var outcome = new Outcome((object)null!);
var outcome = new Outcome<object>((object)null!);
outcome.ToString().Should().BeEmpty();
}

[Fact]
public void GetResultOrThrow_Ok()
{
var outcome = new Outcome<string>("dummy");
outcome.GetResultOrRethrow().Should().Be("dummy");

outcome = new Outcome<string>(new InvalidOperationException());

outcome.Invoking(o => o.GetResultOrRethrow()).Should().Throw<InvalidOperationException>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ namespace Polly.CircuitBreaker;
/// the proportion of actions resulting in a handled exception exceeds <see cref="FailureThreshold"/>,
/// provided also that the number of actions through the circuit in the time-slice is at least <see cref="MinimumThroughput"/>.
/// <para>
/// The circuit will stay broken for the <see cref="CircuitBreakerStrategyOptions.BreakDuration"/>.
/// The circuit will stay broken for the <see cref="CircuitBreakerStrategyOptions{TResult}.BreakDuration"/>.
/// Any attempt to execute this while the circuit is broken, will immediately throw a <see cref="BrokenCircuitException"/> containing the exception
/// that broke the circuit.
/// </para>
/// <para>
/// If the first action after the break duration period results in a handled exception, the circuit will break
/// again for another <see cref="CircuitBreakerStrategyOptions.BreakDuration"/>; if no exception is thrown, the circuit will reset.
/// again for another <see cref="CircuitBreakerStrategyOptions{TResult}.BreakDuration"/>; if no exception is thrown, the circuit will reset.
/// </para>
/// </remarks>
public class AdvancedCircuitBreakerStrategyOptions<TResult> : CircuitBreakerStrategyOptions<TResult>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,6 @@
using System.ComponentModel.DataAnnotations;

namespace Polly.CircuitBreaker;

/// <summary>
/// The options for advanced circuit breaker resilience strategy.
/// </summary>
/// <remarks>
/// The circuit will break if, within any time-slice of duration <see cref="SamplingDuration"/>,
/// the proportion of actions resulting in a handled exception exceeds <see cref="FailureThreshold"/>,
/// provided also that the number of actions through the circuit in the time-slice is at least <see cref="MinimumThroughput"/>.
/// <para>
/// The circuit will stay broken for the <see cref="CircuitBreakerStrategyOptions.BreakDuration"/>.
/// Any attempt to execute this while the circuit is broken, will immediately throw a <see cref="BrokenCircuitException"/> containing the exception
/// that broke the circuit.
/// </para>
/// <para>
/// If the first action after the break duration period results in a handled exception, the circuit will break
/// again for another <see cref="CircuitBreakerStrategyOptions.BreakDuration"/>; if no exception is thrown, the circuit will reset.
/// </para>
/// </remarks>
public class AdvancedCircuitBreakerStrategyOptions : CircuitBreakerStrategyOptions
/// <inheritdoc/>
public class AdvancedCircuitBreakerStrategyOptions : AdvancedCircuitBreakerStrategyOptions<object>
{
/// <summary>
/// Gets or sets the failure threshold at which the circuit will break.
/// </summary>
/// <remarks>
/// A number between zero and one (inclusive) e.g. 0.5 represents breaking if 50% or more of actions result in a handled failure.
/// <para>
/// A ratio number higher than 0, up to 1.
/// Defaults to 0.1 (i.e. 10%).
/// </para>
/// </remarks>
[Range(0, 1.0)]
public double FailureThreshold { get; set; } = CircuitBreakerConstants.DefaultAdvancedFailureThreshold;

/// <summary>
/// Gets or sets the minimum throughput: this many actions or more must pass through the circuit in the time-slice,
/// for statistics to be considered significant and the circuit-breaker to come into action.
/// </summary>
/// <remarks>
/// Value must be 2 or greater.
/// Defaults to 100.
/// </remarks>
[Range(CircuitBreakerConstants.MinimumValidThroughput, int.MaxValue)]
public int MinimumThroughput { get; set; } = CircuitBreakerConstants.DefaultMinimumThroughput;

/// <summary>
/// Gets or sets the duration of the sampling over which failure ratios are assessed.
/// </summary>
/// <remarks>
/// Value must be greater than 20 milliseconds. Defaults to 30 seconds.
/// </remarks>
[TimeSpan("00:00:00.020")]
public TimeSpan SamplingDuration { get; set; } = CircuitBreakerConstants.DefaultSamplingDuration;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Polly.CircuitBreaker;

/// <summary>
/// Arguments used by <see cref="CircuitBreakerStrategyOptions.ShouldHandle"/> predicate.
/// Arguments used by <see cref="CircuitBreakerStrategyOptions{TResult}.ShouldHandle"/> predicate.
/// </summary>
/// <param name="Context">The context associated with the execution of a user-provided callback.</param>
public readonly record struct CircuitBreakerPredicateArguments(ResilienceContext Context) : IResilienceArguments;
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public static ResilienceStrategyBuilder AddSimpleCircuitBreaker(this ResilienceS
return builder.AddStrategy(context => CreateStrategy(context, options, new ConsecutiveFailuresCircuitBehavior(options.FailureThreshold)), options);
}

internal static CircuitBreakerResilienceStrategy CreateStrategy(ResilienceStrategyBuilderContext context, CircuitBreakerStrategyOptions options, CircuitBehavior behavior)
internal static CircuitBreakerResilienceStrategy CreateStrategy(ResilienceStrategyBuilderContext context, CircuitBreakerStrategyOptions<object> options, CircuitBehavior behavior)
{
var controller = new CircuitStateController(
options.BreakDuration,
Expand Down
6 changes: 3 additions & 3 deletions src/Polly.Core/CircuitBreaker/CircuitBreakerStateProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace Polly.CircuitBreaker;
public sealed class CircuitBreakerStateProvider
{
private Func<CircuitState>? _circuitStateProvider;
private Func<Outcome?>? _lastHandledOutcomeProvider;
private Func<Outcome<object>?>? _lastHandledOutcomeProvider;

internal void Initialize(Func<CircuitState> circuitStateProvider, Func<Outcome?> lastHandledOutcomeProvider)
internal void Initialize(Func<CircuitState> circuitStateProvider, Func<Outcome<object>?> lastHandledOutcomeProvider)
{
if (_circuitStateProvider != null)
{
Expand Down Expand Up @@ -40,5 +40,5 @@ internal void Initialize(Func<CircuitState> circuitStateProvider, Func<Outcome?>
/// <remarks>
/// This will be null if no exceptions or results have been handled by the circuit-breaker since the circuit last closed.</remarks>
/// </summary>
public Outcome? LastHandledOutcome => _lastHandledOutcomeProvider?.Invoke();
public Outcome<object>? LastHandledOutcome => _lastHandledOutcomeProvider?.Invoke();
}
116 changes: 0 additions & 116 deletions src/Polly.Core/CircuitBreaker/CircuitBreakerStrategyOptions.TResult.cs

This file was deleted.

Loading

0 comments on commit 63853e2

Please sign in to comment.