Skip to content

Commit e771ba1

Browse files
committed
Drop OutcomeArguments struct
1 parent 8aa9df2 commit e771ba1

File tree

66 files changed

+494
-351
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+494
-351
lines changed

bench/Polly.Core.Benchmarks/PredicateBenchmark.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ namespace Polly.Core.Benchmarks;
55

66
public class PredicateBenchmark
77
{
8-
private readonly OutcomeArguments<HttpResponseMessage, RetryPredicateArguments> _args = new(
8+
private readonly RetryPredicateArguments<HttpResponseMessage> _args = new(
99
ResilienceContextPool.Shared.Get(),
1010
Outcome.FromResult(new HttpResponseMessage(HttpStatusCode.OK)),
11-
new RetryPredicateArguments(0));
11+
0);
1212

1313
private readonly RetryStrategyOptions<HttpResponseMessage> _delegate = new()
1414
{
15-
ShouldHandle = args => args switch
15+
ShouldHandle = args => args.Outcome switch
1616
{
1717
{ Result: { StatusCode: HttpStatusCode.InternalServerError } } => PredicateResult.True,
1818
{ Exception: HttpRequestException } => PredicateResult.True,

bench/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public static object CreateCircuitBreaker(PollyVersion technology)
5252
SamplingDuration = TimeSpan.FromSeconds(30),
5353
MinimumThroughput = 10,
5454
BreakDuration = TimeSpan.FromSeconds(5),
55-
ShouldHandle = args => args switch
55+
ShouldHandle = args => args.Outcome switch
5656
{
5757
{ Exception: InvalidOperationException } => PredicateResult.True,
5858
{ Result: string result } when result == Failure => PredicateResult.True,

bench/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public static ResiliencePipeline<string> CreateHedging()
1212
{
1313
builder.AddHedging(new HedgingStrategyOptions<string>
1414
{
15-
ShouldHandle = args => new ValueTask<bool>(args.Result == Failure),
15+
ShouldHandle = args => new ValueTask<bool>(args.Outcome.Result == Failure),
1616
HedgingActionGenerator = args => () => Outcome.FromResultAsTask("hedged response"),
1717
});
1818
});

bench/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ internal static partial class Helper
2727
BackoffType = RetryBackoffType.Constant,
2828
RetryCount = 3,
2929
BaseDelay = TimeSpan.FromSeconds(1),
30-
ShouldHandle = args => args switch
30+
ShouldHandle = args => args.Outcome switch
3131
{
3232
{ Exception: InvalidOperationException } => PredicateResult.True,
3333
{ Result: var result } when result == Failure => PredicateResult.True,
@@ -41,7 +41,7 @@ internal static partial class Helper
4141
SamplingDuration = TimeSpan.FromSeconds(30),
4242
MinimumThroughput = 10,
4343
BreakDuration = TimeSpan.FromSeconds(5),
44-
ShouldHandle = args => args switch
44+
ShouldHandle = args => args.Outcome switch
4545
{
4646
{ Exception: InvalidOperationException } => PredicateResult.True,
4747
{ Result: string result } when result == Failure => PredicateResult.True,
@@ -71,7 +71,7 @@ public static ResiliencePipeline CreateNonGenericStrategyPipeline(bool telemetry
7171
BackoffType = RetryBackoffType.Constant,
7272
RetryCount = 3,
7373
BaseDelay = TimeSpan.FromSeconds(1),
74-
ShouldHandle = args => args switch
74+
ShouldHandle = args => args.Outcome switch
7575
{
7676
{ Exception: InvalidOperationException } => PredicateResult.True,
7777
{ Result: string result } when result == Failure => PredicateResult.True,
@@ -85,7 +85,7 @@ public static ResiliencePipeline CreateNonGenericStrategyPipeline(bool telemetry
8585
SamplingDuration = TimeSpan.FromSeconds(30),
8686
MinimumThroughput = 10,
8787
BreakDuration = TimeSpan.FromSeconds(5),
88-
ShouldHandle = args => args switch
88+
ShouldHandle = args => args.Outcome switch
8989
{
9090
{ Exception: InvalidOperationException } => PredicateResult.True,
9191
{ Result: string result } when result == Failure => PredicateResult.True,

bench/Polly.Core.Benchmarks/Utils/Helper.Retry.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public static object CreateRetry(PollyVersion technology)
2121
RetryCount = 3,
2222
BackoffType = RetryBackoffType.Constant,
2323
BaseDelay = delay,
24-
ShouldHandle = args => args switch
24+
ShouldHandle = args => args.Outcome switch
2525
{
2626
{ Exception: InvalidOperationException } => PredicateResult.True,
2727
{ Result: string result } when result == Failure => PredicateResult.True,
Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,34 @@
11
namespace Polly.CircuitBreaker;
22

3+
#pragma warning disable CA1815 // Override equals and operator equals on value types
4+
35
/// <summary>
46
/// Arguments used by <see cref="CircuitBreakerStrategyOptions{TResult}.ShouldHandle"/> predicate.
57
/// </summary>
8+
/// <typeparam name="TResult">The type of result.</typeparam>
69
/// <remarks>
710
/// Always use the constructor when creating this struct, otherwise we do not guarantee binary compatibility.
811
/// </remarks>
9-
public readonly struct CircuitBreakerPredicateArguments
12+
public readonly struct CircuitBreakerPredicateArguments<TResult> : IOutcomeArguments<TResult>
1013
{
14+
/// <summary>
15+
/// Initializes a new instance of the <see cref="CircuitBreakerPredicateArguments{TResult}"/> struct.
16+
/// </summary>
17+
/// <param name="outcome">The context in which the resilience operation or event occurred.</param>
18+
/// <param name="context">The outcome of the resilience operation or event.</param>
19+
public CircuitBreakerPredicateArguments(ResilienceContext context, Outcome<TResult> outcome)
20+
{
21+
Context = context;
22+
Outcome = outcome;
23+
}
24+
25+
/// <summary>
26+
/// Gets the outcome of the resilience operation or event.
27+
/// </summary>
28+
public Outcome<TResult> Outcome { get; }
29+
30+
/// <summary>
31+
/// Gets the context in which the resilience operation or event occurred.
32+
/// </summary>
33+
public ResilienceContext Context { get; }
1134
}

src/Polly.Core/CircuitBreaker/CircuitBreakerResilienceStrategy.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ namespace Polly.CircuitBreaker;
22

33
internal sealed class CircuitBreakerResilienceStrategy<T> : ResilienceStrategy<T>, IDisposable
44
{
5-
private readonly Func<OutcomeArguments<T, CircuitBreakerPredicateArguments>, ValueTask<bool>> _handler;
5+
private readonly Func<CircuitBreakerPredicateArguments<T>, ValueTask<bool>> _handler;
66
private readonly CircuitStateController<T> _controller;
77
private readonly IDisposable? _manualControlRegistration;
88

99
public CircuitBreakerResilienceStrategy(
10-
Func<OutcomeArguments<T, CircuitBreakerPredicateArguments>, ValueTask<bool>> handler,
10+
Func<CircuitBreakerPredicateArguments<T>, ValueTask<bool>> handler,
1111
CircuitStateController<T> controller,
1212
CircuitBreakerStateProvider? stateProvider,
1313
CircuitBreakerManualControl? manualControl)
@@ -36,7 +36,7 @@ protected internal override async ValueTask<Outcome<T>> ExecuteCore<TState>(Func
3636

3737
outcome = await StrategyHelper.ExecuteCallbackSafeAsync(callback, context, state).ConfigureAwait(context.ContinueOnCapturedContext);
3838

39-
var args = new OutcomeArguments<T, CircuitBreakerPredicateArguments>(context, outcome, default);
39+
var args = new CircuitBreakerPredicateArguments<T>(context, outcome);
4040
if (await _handler(args).ConfigureAwait(context.ContinueOnCapturedContext))
4141
{
4242
await _controller.OnActionFailureAsync(outcome, context).ConfigureAwait(context.ContinueOnCapturedContext);

src/Polly.Core/CircuitBreaker/CircuitBreakerStrategyOptions.TResult.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public class CircuitBreakerStrategyOptions<TResult> : ResilienceStrategyOptions
7777
/// This property is required.
7878
/// </value>
7979
[Required]
80-
public Func<OutcomeArguments<TResult, CircuitBreakerPredicateArguments>, ValueTask<bool>> ShouldHandle { get; set; } = DefaultPredicates<CircuitBreakerPredicateArguments, TResult>.HandleOutcome;
80+
public Func<CircuitBreakerPredicateArguments<TResult>, ValueTask<bool>> ShouldHandle { get; set; } = DefaultPredicates<CircuitBreakerPredicateArguments<TResult>, TResult>.HandleOutcome;
8181

8282
/// <summary>
8383
/// Gets or sets the event that is raised when the circuit resets to a <see cref="CircuitState.Closed"/> state.
@@ -93,7 +93,7 @@ public class CircuitBreakerStrategyOptions<TResult> : ResilienceStrategyOptions
9393
/// </para>
9494
/// </remarks>
9595
/// <value>The default value is <see langword="null"/>.</value>
96-
public Func<OutcomeArguments<TResult, OnCircuitClosedArguments>, ValueTask>? OnClosed { get; set; }
96+
public Func<OnCircuitClosedArguments<TResult>, ValueTask>? OnClosed { get; set; }
9797

9898
/// <summary>
9999
/// Gets or sets the event that is raised when the circuit transitions to an <see cref="CircuitState.Open"/> state.
@@ -109,7 +109,7 @@ public class CircuitBreakerStrategyOptions<TResult> : ResilienceStrategyOptions
109109
/// </para>
110110
/// </remarks>
111111
/// <value>The default value is <see langword="null"/>.</value>
112-
public Func<OutcomeArguments<TResult, OnCircuitOpenedArguments>, ValueTask>? OnOpened { get; set; }
112+
public Func<OnCircuitOpenedArguments<TResult>, ValueTask>? OnOpened { get; set; }
113113

114114
/// <summary>
115115
/// Gets or sets the event that is raised when when the circuit transitions to an <see cref="CircuitState.HalfOpen"/> state.

src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ internal sealed class CircuitStateController<T> : IDisposable
99
{
1010
private readonly object _lock = new();
1111
private readonly ScheduledTaskExecutor _executor = new();
12-
private readonly Func<OutcomeArguments<T, OnCircuitOpenedArguments>, ValueTask>? _onOpened;
13-
private readonly Func<OutcomeArguments<T, OnCircuitClosedArguments>, ValueTask>? _onClosed;
12+
private readonly Func<OnCircuitOpenedArguments<T>, ValueTask>? _onOpened;
13+
private readonly Func<OnCircuitClosedArguments<T>, ValueTask>? _onClosed;
1414
private readonly Func<OnCircuitHalfOpenedArguments, ValueTask>? _onHalfOpen;
1515
private readonly TimeProvider _timeProvider;
1616
private readonly ResilienceStrategyTelemetry _telemetry;
@@ -24,8 +24,8 @@ internal sealed class CircuitStateController<T> : IDisposable
2424

2525
public CircuitStateController(
2626
TimeSpan breakDuration,
27-
Func<OutcomeArguments<T, OnCircuitOpenedArguments>, ValueTask>? onOpened,
28-
Func<OutcomeArguments<T, OnCircuitClosedArguments>, ValueTask>? onClosed,
27+
Func<OnCircuitOpenedArguments<T>, ValueTask>? onOpened,
28+
Func<OnCircuitClosedArguments<T>, ValueTask>? onClosed,
2929
Func<OnCircuitHalfOpenedArguments, ValueTask>? onHalfOpen,
3030
CircuitBehavior behavior,
3131
TimeProvider timeProvider,
@@ -268,8 +268,8 @@ private void CloseCircuit_NeedsLock(Outcome<T> outcome, bool manual, ResilienceC
268268

269269
if (priorState != CircuitState.Closed)
270270
{
271-
var args = new OutcomeArguments<T, OnCircuitClosedArguments>(context, outcome, new OnCircuitClosedArguments(manual));
272-
_telemetry.Report(new(ResilienceEventSeverity.Information, CircuitBreakerConstants.OnCircuitClosed), args);
271+
var args = new OnCircuitClosedArguments<T>(context, outcome, manual);
272+
_telemetry.Report<OnCircuitClosedArguments<T>, T>(new(ResilienceEventSeverity.Information, CircuitBreakerConstants.OnCircuitClosed), args);
273273

274274
if (_onClosed is not null)
275275
{
@@ -319,8 +319,8 @@ private void OpenCircuitFor_NeedsLock(Outcome<T> outcome, TimeSpan breakDuration
319319
var transitionedState = _circuitState;
320320
_circuitState = CircuitState.Open;
321321

322-
var args = new OutcomeArguments<T, OnCircuitOpenedArguments>(context, outcome, new OnCircuitOpenedArguments(breakDuration, manual));
323-
_telemetry.Report(new(ResilienceEventSeverity.Error, CircuitBreakerConstants.OnCircuitOpened), args);
322+
var args = new OnCircuitOpenedArguments<T>(context, outcome, breakDuration, manual);
323+
_telemetry.Report<OnCircuitOpenedArguments<T>, T>(new(ResilienceEventSeverity.Error, CircuitBreakerConstants.OnCircuitOpened), args);
324324

325325
if (_onOpened is not null)
326326
{

src/Polly.Core/CircuitBreaker/OnCircuitClosedArguments.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,34 @@ namespace Polly.CircuitBreaker;
55
/// <summary>
66
/// Arguments used by <see cref="CircuitBreakerStrategyOptions{TResult}.OnClosed"/> event.
77
/// </summary>
8+
/// <typeparam name="TResult">The type of result.</typeparam>
89
/// <remarks>
910
/// Always use the constructor when creating this struct, otherwise we do not guarantee binary compatibility.
1011
/// </remarks>
11-
public readonly struct OnCircuitClosedArguments
12+
public readonly struct OnCircuitClosedArguments<TResult> : IOutcomeArguments<TResult>
1213
{
1314
/// <summary>
14-
/// Initializes a new instance of the <see cref="OnCircuitClosedArguments"/> struct.
15+
/// Initializes a new instance of the <see cref="OnCircuitClosedArguments{TResult}"/> struct.
1516
/// </summary>
17+
/// <param name="outcome">The context in which the resilience operation or event occurred.</param>
18+
/// <param name="context">The outcome of the resilience operation or event.</param>
1619
/// <param name="isManual">Indicates whether the circuit was closed manually by using <see cref="CircuitBreakerManualControl"/>.</param>
17-
public OnCircuitClosedArguments(bool isManual) => IsManual = isManual;
20+
public OnCircuitClosedArguments(ResilienceContext context, Outcome<TResult> outcome, bool isManual)
21+
{
22+
Context = context;
23+
Outcome = outcome;
24+
IsManual = isManual;
25+
}
26+
27+
/// <summary>
28+
/// Gets the outcome of the resilience operation or event.
29+
/// </summary>
30+
public Outcome<TResult> Outcome { get; }
31+
32+
/// <summary>
33+
/// Gets the context in which the resilience operation or event occurred.
34+
/// </summary>
35+
public ResilienceContext Context { get; }
1836

1937
/// <summary>
2038
/// Gets a value indicating whether the circuit was closed manually by using <see cref="CircuitBreakerManualControl"/>.

0 commit comments

Comments
 (0)