Skip to content

Commit

Permalink
Add outcome to the break duration generator arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
peter-csala committed Jul 16, 2024
1 parent 1eb48d7 commit 3bdcafb
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 24 deletions.
26 changes: 17 additions & 9 deletions src/Polly.Core/CircuitBreaker/BreakDurationGeneratorArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,31 @@ namespace Polly.CircuitBreaker;
/// <summary>
/// Represents arguments used to generate a dynamic break duration for a circuit breaker.
/// </summary>
public readonly struct BreakDurationGeneratorArguments
/// <typeparam name="TResult">The type of result.</typeparam>
public readonly struct BreakDurationGeneratorArguments<TResult>
{
/// <summary>
/// Initializes a new instance of the <see cref="BreakDurationGeneratorArguments"/> struct.
/// Initializes a new instance of the <see cref="BreakDurationGeneratorArguments{TResult}"/> struct.
/// </summary>
/// <param name="failureRate">The failure rate at which the circuit breaker should trip.
/// It represents the ratio of failed actions to the total executed actions.</param>
/// <param name="failureCount">The number of failures that have occurred.
/// This count is used to determine if the failure threshold has been reached.</param>
/// <param name="context">The resilience context providing additional information
/// about the execution state and failures.</param>
/// <param name="outcome">The outcome of the resilience operation or event.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public BreakDurationGeneratorArguments(
double failureRate,
int failureCount,
ResilienceContext context)
ResilienceContext context,
Outcome<TResult> outcome)
: this(failureRate, failureCount, context, 0, outcome)
{
FailureRate = failureRate;
FailureCount = failureCount;
Context = context;
HalfOpenAttempts = 0;
}

/// <summary>
/// Initializes a new instance of the <see cref="BreakDurationGeneratorArguments"/> struct.
/// Initializes a new instance of the <see cref="BreakDurationGeneratorArguments{TResult}"/> struct.
/// </summary>
/// <param name="failureRate">The failure rate at which the circuit breaker should trip.
/// It represents the ratio of failed actions to the total executed actions.</param>
Expand All @@ -40,16 +40,19 @@ public BreakDurationGeneratorArguments(
/// <param name="context">The resilience context providing additional information
/// about the execution state and failures.</param>
/// <param name="halfOpenAttempts">The number of half-open attempts.</param>
/// <param name="outcome">The outcome of the resilience operation or event.</param>
public BreakDurationGeneratorArguments(
double failureRate,
int failureCount,
ResilienceContext context,
int halfOpenAttempts)
int halfOpenAttempts,
Outcome<TResult> outcome)
{
FailureRate = failureRate;
FailureCount = failureCount;
Context = context;
HalfOpenAttempts = halfOpenAttempts;
Outcome = outcome;
}

/// <summary>
Expand All @@ -71,4 +74,9 @@ public BreakDurationGeneratorArguments(
/// Gets the number of half-open attempts.
/// </summary>
public int HalfOpenAttempts { get; }

/// <summary>
/// Gets the outcome of the user-specified callback.
/// </summary>
public Outcome<TResult> Outcome { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class CircuitBreakerStrategyOptions<TResult> : ResilienceStrategyOptions
/// <value>
/// The default value is <see langword="null"/>.
/// </value>
public Func<BreakDurationGeneratorArguments, ValueTask<TimeSpan>>? BreakDurationGenerator { get; set; }
public Func<BreakDurationGeneratorArguments<TResult>, ValueTask<TimeSpan>>? BreakDurationGenerator { get; set; }

/// <summary>
/// Gets or sets a predicate that determines whether the outcome should be handled by the circuit breaker.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ internal sealed class CircuitStateController<T> : IDisposable
private readonly ResilienceStrategyTelemetry _telemetry;
private readonly CircuitBehavior _behavior;
private readonly TimeSpan _breakDuration;
private readonly Func<BreakDurationGeneratorArguments, ValueTask<TimeSpan>>? _breakDurationGenerator;
private readonly Func<BreakDurationGeneratorArguments<T>, ValueTask<TimeSpan>>? _breakDurationGenerator;
private DateTimeOffset _blockedUntil;
private CircuitState _circuitState = CircuitState.Closed;
private Outcome<T>? _lastOutcome;
Expand All @@ -33,7 +33,7 @@ public CircuitStateController(
CircuitBehavior behavior,
TimeProvider timeProvider,
ResilienceStrategyTelemetry telemetry,
Func<BreakDurationGeneratorArguments, ValueTask<TimeSpan>>? breakDurationGenerator)
Func<BreakDurationGeneratorArguments<T>, ValueTask<TimeSpan>>? breakDurationGenerator)
#pragma warning restore S107
{
_breakDuration = breakDuration;
Expand Down Expand Up @@ -323,7 +323,7 @@ private void OpenCircuitFor_NeedsLock(Outcome<T> outcome, TimeSpan breakDuration
{
#pragma warning disable CA2012
#pragma warning disable S1226
breakDuration = _breakDurationGenerator(new(_behavior.FailureRate, _behavior.FailureCount, context, _halfOpenAttempts)).GetAwaiter().GetResult();
breakDuration = _breakDurationGenerator(new(_behavior.FailureRate, _behavior.FailureCount, context, _halfOpenAttempts, outcome)).GetAwaiter().GetResult();
#pragma warning restore S1226
#pragma warning restore CA2012
}
Expand Down
19 changes: 10 additions & 9 deletions src/Polly.Core/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ override Polly.Registry.ResiliencePipelineRegistry<TKey>.TryGetPipeline(TKey key
override Polly.Registry.ResiliencePipelineRegistry<TKey>.TryGetPipeline<TResult>(TKey key, out Polly.ResiliencePipeline<TResult>? pipeline) -> bool
override Polly.ResiliencePropertyKey<TValue>.ToString() -> string!
override Polly.Telemetry.ResilienceEvent.ToString() -> string!
Polly.CircuitBreaker.BreakDurationGeneratorArguments
Polly.CircuitBreaker.BreakDurationGeneratorArguments.BreakDurationGeneratorArguments() -> void
Polly.CircuitBreaker.BreakDurationGeneratorArguments.BreakDurationGeneratorArguments(double failureRate, int failureCount, Polly.ResilienceContext! context) -> void
Polly.CircuitBreaker.BreakDurationGeneratorArguments.BreakDurationGeneratorArguments(double failureRate, int failureCount, Polly.ResilienceContext! context, int halfOpenAttempts) -> void
Polly.CircuitBreaker.BreakDurationGeneratorArguments.Context.get -> Polly.ResilienceContext!
Polly.CircuitBreaker.BreakDurationGeneratorArguments.FailureCount.get -> int
Polly.CircuitBreaker.BreakDurationGeneratorArguments.FailureRate.get -> double
Polly.CircuitBreaker.BreakDurationGeneratorArguments.HalfOpenAttempts.get -> int
Polly.CircuitBreaker.BreakDurationGeneratorArguments<TResult>
Polly.CircuitBreaker.BreakDurationGeneratorArguments<TResult>.BreakDurationGeneratorArguments() -> void
Polly.CircuitBreaker.BreakDurationGeneratorArguments<TResult>.BreakDurationGeneratorArguments(double failureRate, int failureCount, Polly.ResilienceContext! context, Polly.Outcome<TResult> outcome) -> void
Polly.CircuitBreaker.BreakDurationGeneratorArguments<TResult>.BreakDurationGeneratorArguments(double failureRate, int failureCount, Polly.ResilienceContext! context, int halfOpenAttempts, Polly.Outcome<TResult> outcome) -> void
Polly.CircuitBreaker.BreakDurationGeneratorArguments<TResult>.Context.get -> Polly.ResilienceContext!
Polly.CircuitBreaker.BreakDurationGeneratorArguments<TResult>.FailureCount.get -> int
Polly.CircuitBreaker.BreakDurationGeneratorArguments<TResult>.FailureRate.get -> double
Polly.CircuitBreaker.BreakDurationGeneratorArguments<TResult>.HalfOpenAttempts.get -> int
Polly.CircuitBreaker.BreakDurationGeneratorArguments<TResult>.Outcome.get -> Polly.Outcome<TResult>
Polly.CircuitBreaker.BrokenCircuitException
Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException() -> void
Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(string! message) -> void
Expand All @@ -41,7 +42,7 @@ Polly.CircuitBreaker.CircuitBreakerStrategyOptions.CircuitBreakerStrategyOptions
Polly.CircuitBreaker.CircuitBreakerStrategyOptions<TResult>
Polly.CircuitBreaker.CircuitBreakerStrategyOptions<TResult>.BreakDuration.get -> System.TimeSpan
Polly.CircuitBreaker.CircuitBreakerStrategyOptions<TResult>.BreakDuration.set -> void
Polly.CircuitBreaker.CircuitBreakerStrategyOptions<TResult>.BreakDurationGenerator.get -> System.Func<Polly.CircuitBreaker.BreakDurationGeneratorArguments, System.Threading.Tasks.ValueTask<System.TimeSpan>>?
Polly.CircuitBreaker.CircuitBreakerStrategyOptions<TResult>.BreakDurationGenerator.get -> System.Func<Polly.CircuitBreaker.BreakDurationGeneratorArguments<TResult>, System.Threading.Tasks.ValueTask<System.TimeSpan>>?
Polly.CircuitBreaker.CircuitBreakerStrategyOptions<TResult>.BreakDurationGenerator.set -> void
Polly.CircuitBreaker.CircuitBreakerStrategyOptions<TResult>.CircuitBreakerStrategyOptions() -> void
Polly.CircuitBreaker.CircuitBreakerStrategyOptions<TResult>.FailureRatio.get -> double
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ public void Constructor_Old_Ok()
double expectedFailureRate = 0.5;
int failureCount = 10;
var context = new ResilienceContext();
var outcome = Outcome.FromResult(42);

var args = new BreakDurationGeneratorArguments(expectedFailureRate, failureCount, context);
var args = new BreakDurationGeneratorArguments<int>(expectedFailureRate, failureCount, context, outcome);

args.FailureRate.Should().Be(expectedFailureRate);
args.FailureCount.Should().Be(failureCount);
args.Context.Should().Be(context);
args.Outcome.Should().Be(outcome);
}

[Fact]
Expand All @@ -25,12 +27,14 @@ public void Constructor_Ok()
double expectedFailureRate = 0.5;
int failureCount = 10;
var context = new ResilienceContext();
var outcome = Outcome.FromResult(42);

var args = new BreakDurationGeneratorArguments(expectedFailureRate, failureCount, context, 99);
var args = new BreakDurationGeneratorArguments<int>(expectedFailureRate, failureCount, context, 99, outcome);

args.FailureRate.Should().Be(expectedFailureRate);
args.FailureCount.Should().Be(failureCount);
args.Context.Should().Be(context);
args.HalfOpenAttempts.Should().Be(99);
args.Outcome.Should().Be(outcome);
}
}

0 comments on commit 3bdcafb

Please sign in to comment.