Skip to content

Commit

Permalink
Introduce OutcomeArguments and use them in delegates
Browse files Browse the repository at this point in the history
  • Loading branch information
martintmk committed Jun 5, 2023
1 parent 2201aaf commit 88d8612
Show file tree
Hide file tree
Showing 95 changed files with 503 additions and 460 deletions.
4 changes: 2 additions & 2 deletions src/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static object CreateOpenedCircuitBreaker(PollyVersion version, bool handl
var manualControl = new CircuitBreakerManualControl();
var options = new AdvancedCircuitBreakerStrategyOptions
{
ShouldHandle = (_, _) => PredicateResult.True,
ShouldHandle = _ => PredicateResult.True,
ManualControl = manualControl,
};

Expand Down Expand Up @@ -56,7 +56,7 @@ public static object CreateCircuitBreaker(PollyVersion technology)
SamplingDuration = TimeSpan.FromSeconds(30),
MinimumThroughput = 10,
BreakDuration = TimeSpan.FromSeconds(5),
ShouldHandle = (outcome, _) => outcome switch
ShouldHandle = args => args switch
{
{ Exception: InvalidOperationException } => PredicateResult.True,
{ Result: string result } when result == Failure => PredicateResult.True,
Expand Down
2 changes: 1 addition & 1 deletion src/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static ResilienceStrategy<string> CreateHedging()
{
builder.AddHedging(new HedgingStrategyOptions<string>
{
ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Result == Failure),
ShouldHandle = args => new ValueTask<bool>(args.Result == Failure),
HedgingActionGenerator = args => () => Task.FromResult("hedged response"),
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal static partial class Helper
SamplingDuration = TimeSpan.FromSeconds(30),
MinimumThroughput = 10,
BreakDuration = TimeSpan.FromSeconds(5),
ShouldHandle = (outcome, _) => outcome switch
ShouldHandle = args => args switch
{
{ Exception: InvalidOperationException } => PredicateResult.True,
{ Result: string result } when result == Failure => PredicateResult.True,
Expand Down
4 changes: 2 additions & 2 deletions src/Polly.Core.Benchmarks/Utils/Helper.Retry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ public static object CreateRetry(PollyVersion technology)
RetryCount = 3,
BackoffType = RetryBackoffType.Constant,
BaseDelay = delay,
ShouldRetry = (outcome, _) => outcome switch
ShouldRetry = args => args switch
{
{ Exception: InvalidOperationException } => PredicateResult.True,
{ Result: string result } when result == Failure => PredicateResult.True,
_ => PredicateResult.False
},
OnRetry = (_, _) => default
OnRetry = _ => default
});
}),
_ => throw new NotSupportedException()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void Ctor_Defaults()
options.MinimumThroughput = 2;
options.SamplingDuration = TimeSpan.FromMilliseconds(500);

options.ShouldHandle = (_, _) => PredicateResult.True;
options.ShouldHandle = _ => PredicateResult.True;
ValidationHelper.ValidateObject(options, "Dummy.");
}

Expand All @@ -55,7 +55,7 @@ public void Ctor_Generic_Defaults()
options.MinimumThroughput = 2;
options.SamplingDuration = TimeSpan.FromMilliseconds(500);

options.ShouldHandle = (_, _) => PredicateResult.True;
options.ShouldHandle = _ => PredicateResult.True;
ValidationHelper.ValidateObject(options, "Dummy.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ public class CircuitBreakerPredicateArgumentsTests
[Fact]
public void Ctor_Ok()
{
var context = ResilienceContext.Get();

var args = new CircuitBreakerPredicateArguments(context);

args.Context.Should().Be(context);
this.Invoking(_ => new CircuitBreakerPredicateArguments()).Should().NotThrow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ public class CircuitBreakerResilienceStrategyBuilderTests
{
builder => builder.AddAdvancedCircuitBreaker(new AdvancedCircuitBreakerStrategyOptions
{
ShouldHandle = (_, _) => PredicateResult.True
ShouldHandle = _ => PredicateResult.True
}),
builder => builder.AddSimpleCircuitBreaker(new SimpleCircuitBreakerStrategyOptions
{
ShouldHandle = (_, _) => PredicateResult.True
ShouldHandle = _ => PredicateResult.True
}),
};

public static TheoryData<Action<ResilienceStrategyBuilder<int>>> ConfigureDataGeneric = new()
{
builder => builder.AddAdvancedCircuitBreaker(new AdvancedCircuitBreakerStrategyOptions<int>
{
ShouldHandle = (_, _) => PredicateResult.True
ShouldHandle = _ => PredicateResult.True
}),
builder => builder.AddSimpleCircuitBreaker(new SimpleCircuitBreakerStrategyOptions<int>
{
ShouldHandle = (_, _) => PredicateResult.True
ShouldHandle = _ => PredicateResult.True
}),
};

Expand Down Expand Up @@ -100,9 +100,9 @@ public void AddCircuitBreaker_IntegrationTest()
{
FailureThreshold = 5,
BreakDuration = TimeSpan.FromMilliseconds(500),
ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Result is -1),
OnOpened = (_, _) => { opened++; return default; },
OnClosed = (_, _) => { closed++; return default; },
ShouldHandle = args => new ValueTask<bool>(args.Result is -1),
OnOpened = _ => { opened++; return default; },
OnClosed = _ => { closed++; return default; },
OnHalfOpened = (_) => { halfOpened++; return default; }
};

Expand Down Expand Up @@ -151,9 +151,9 @@ public void AddAdvancedCircuitBreaker_IntegrationTest()
MinimumThroughput = 10,
SamplingDuration = TimeSpan.FromSeconds(10),
BreakDuration = TimeSpan.FromSeconds(1),
ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Result is -1),
OnOpened = (_, _) => { opened++; return default; },
OnClosed = (_, _) => { closed++; return default; },
ShouldHandle = args => new ValueTask<bool>(args.Result is -1),
OnOpened = _ => { opened++; return default; },
OnClosed = _ => { closed++; return default; },
OnHalfOpened = (_) => { halfOpened++; return default; }
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void Ctor_StateProvider_EnsureAttached()
[Fact]
public async Task Ctor_ManualControl_EnsureAttached()
{
_options.ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Exception is InvalidOperationException);
_options.ShouldHandle = args => new ValueTask<bool>(args.Exception is InvalidOperationException);
_options.ManualControl = new CircuitBreakerManualControl();
var strategy = Create();

Expand All @@ -74,7 +74,7 @@ public async Task Ctor_ManualControl_EnsureAttached()
[Fact]
public void Execute_HandledResult_OnFailureCalled()
{
_options.ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Result is -1);
_options.ShouldHandle = args => new ValueTask<bool>(args.Result is -1);
var strategy = Create();
var shouldBreak = false;

Expand All @@ -87,7 +87,7 @@ public void Execute_HandledResult_OnFailureCalled()
[Fact]
public void Execute_UnhandledResult_OnActionSuccess()
{
_options.ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Result is -1);
_options.ShouldHandle = args => new ValueTask<bool>(args.Result is -1);
var strategy = Create();

_behavior.Setup(v => v.OnActionSuccess(CircuitState.Closed));
Expand All @@ -99,7 +99,7 @@ public void Execute_UnhandledResult_OnActionSuccess()
[Fact]
public void Execute_HandledException_OnFailureCalled()
{
_options.ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Exception is InvalidOperationException);
_options.ShouldHandle = args => new ValueTask<bool>(args.Exception is InvalidOperationException);
var strategy = Create();
var shouldBreak = false;

Expand All @@ -113,7 +113,7 @@ public void Execute_HandledException_OnFailureCalled()
[Fact]
public void Execute_UnhandledException_NoCalls()
{
_options.ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Exception is InvalidOperationException);
_options.ShouldHandle = args => new ValueTask<bool>(args.Exception is InvalidOperationException);
var strategy = Create();

strategy.Invoking(s => s.Execute(_ => throw new ArgumentException())).Should().Throw<ArgumentException>();
Expand All @@ -126,7 +126,7 @@ public void Execute_UnhandledException_NoCalls()
[Fact]
public void Execute_Ok()
{
_options.ShouldHandle = (_, _) => PredicateResult.False;
_options.ShouldHandle = _ => PredicateResult.False;
_behavior.Setup(v => v.OnActionSuccess(CircuitState.Closed));

Create().Invoking(s => s.Execute(_ => { })).Should().NotThrow();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class CircuitStateControllerTests
private readonly FakeTimeProvider _timeProvider = new();
private readonly CircuitBreakerStrategyOptions<object> _options = new SimpleCircuitBreakerStrategyOptions();
private readonly Mock<CircuitBehavior> _circuitBehavior = new(MockBehavior.Strict);
private readonly Action<IResilienceArguments> _onTelemetry = _ => { };
private readonly Action<object> _onTelemetry = _ => { };
private DateTimeOffset _utcNow = DateTimeOffset.UtcNow;

public CircuitStateControllerTests() => _timeProvider.Setup(v => v.UtcNow).Returns(() => _utcNow);
Expand All @@ -30,13 +30,13 @@ public async Task IsolateAsync_Ok()
{
// arrange
bool called = false;
_options.OnOpened = (outcome, args) =>
_options.OnOpened = args =>
{
args.BreakDuration.Should().Be(TimeSpan.MaxValue);
args.Arguments.BreakDuration.Should().Be(TimeSpan.MaxValue);
args.Context.IsSynchronous.Should().BeFalse();
args.Context.IsVoid.Should().BeTrue();
args.IsManual.Should().BeTrue();
outcome.IsVoidResult.Should().BeTrue();
args.Arguments.IsManual.Should().BeTrue();
args.Outcome.IsVoidResult.Should().BeTrue();
called = true;
return default;
};
Expand Down Expand Up @@ -67,12 +67,12 @@ public async Task BreakAsync_Ok()
{
// arrange
bool called = false;
_options.OnClosed = (outcome, args) =>
_options.OnClosed = args =>
{
args.Context.IsSynchronous.Should().BeFalse();
args.Context.IsVoid.Should().BeTrue();
args.IsManual.Should().BeTrue();
outcome.IsVoidResult.Should().BeTrue();
args.Arguments.IsManual.Should().BeTrue();
args.Outcome.IsVoidResult.Should().BeTrue();
called = true;
return default;
};
Expand Down Expand Up @@ -232,9 +232,9 @@ public async Task OnActionSuccess_EnsureCorrectBehavior(CircuitState state, Circ
{
// arrange
var called = false;
_options.OnClosed = (_, args) =>
_options.OnClosed = args =>
{
args.IsManual.Should().BeFalse();
args.Arguments.IsManual.Should().BeFalse();
called = true;
return default;
};
Expand Down Expand Up @@ -272,15 +272,15 @@ public async Task OnActionFailureAsync_EnsureCorrectBehavior(CircuitState state,
{
// arrange
var called = false;
_options.OnOpened = (_, args) =>
_options.OnOpened = args =>
{
if (state == CircuitState.Isolated)
{
args.IsManual.Should().BeTrue();
args.Arguments.IsManual.Should().BeTrue();
}
else
{
args.IsManual.Should().BeFalse();
args.Arguments.IsManual.Should().BeFalse();
}

called = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ public class OnCircuitClosedArgumentsTests
[Fact]
public void Ctor_Ok()
{
var context = ResilienceContext.Get();

var args = new OnCircuitClosedArguments(context, true);

args.Context.Should().Be(context);
var args = new OnCircuitClosedArguments(true);
args.IsManual.Should().BeTrue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ public class OnCircuitHalfOpenedArgumentsTests
[Fact]
public void Ctor_Ok()
{
var context = ResilienceContext.Get();

var args = new OnCircuitHalfOpenedArguments(context);

args.Context.Should().Be(context);
this.Invoking(_ => new OnCircuitHalfOpenedArguments()).Should().NotThrow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ public class OnCircuitOpenedArgumentsTests
[Fact]
public void Ctor_Ok()
{
var context = ResilienceContext.Get();
var args = new OnCircuitOpenedArguments(TimeSpan.FromSeconds(2), true);

var args = new OnCircuitOpenedArguments(context, TimeSpan.FromSeconds(2), true);

args.Context.Should().Be(context);
args.BreakDuration.Should().Be(TimeSpan.FromSeconds(2));
args.IsManual.Should().BeTrue();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void Ctor_Defaults()
options.FailureThreshold = 1;
options.BreakDuration = TimeSpan.FromMilliseconds(500);

options.ShouldHandle = (_, _) => PredicateResult.True;
options.ShouldHandle = _ => PredicateResult.True;
ValidationHelper.ValidateObject(options, "Dummy.");
}

Expand All @@ -48,7 +48,7 @@ public void Ctor_Generic_Defaults()
options.FailureThreshold = 1;
options.BreakDuration = TimeSpan.FromMilliseconds(500);

options.ShouldHandle = (_, _) => PredicateResult.True;
options.ShouldHandle = _ => PredicateResult.True;
ValidationHelper.ValidateObject(options, "Dummy.");
}

Expand Down
37 changes: 19 additions & 18 deletions src/Polly.Core.Tests/Fallback/FallbackHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,17 @@ public async Task SetFallback_Ok()
var handler = new FallbackHandler()
.SetFallback<int>(handler =>
{
handler.FallbackAction = (_, _) => new ValueTask<int>(0);
handler.ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Result == -1);
handler.FallbackAction = _ => new ValueTask<int>(0);
handler.ShouldHandle = args => new ValueTask<bool>(args.Result == -1);
})
.CreateHandler();

var args = new HandleFallbackArguments(ResilienceContext.Get());
var args = new HandleFallbackArguments();
handler.Should().NotBeNull();
var action = await handler!.ShouldHandleAsync(new Outcome<int>(-1), args);
(await action!(new Outcome<int>(-1), args)).Should().Be(0);
var action = await handler!.ShouldHandleAsync<int>(new(ResilienceContext.Get(), new Outcome<int>(-1), args));
(await action!(new(ResilienceContext.Get(), new Outcome<int>(-1), args))).Should().Be(0);

action = await handler!.ShouldHandleAsync(new Outcome<int>(0), args);
action = await handler!.ShouldHandleAsync<int>(new(ResilienceContext.Get(), new Outcome<int>(0), args));
action.Should().BeNull();
}

Expand All @@ -84,18 +84,18 @@ public async Task SetVoidFallback_Ok()
var handler = new FallbackHandler()
.SetVoidFallback(handler =>
{
handler.FallbackAction = (_, _) => default;
handler.ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Exception is InvalidOperationException);
handler.FallbackAction = _ => default;
handler.ShouldHandle = args => new ValueTask<bool>(args.Exception is InvalidOperationException);
})
.CreateHandler();

var args = new HandleFallbackArguments(ResilienceContext.Get());
var args = new HandleFallbackArguments();
handler.Should().NotBeNull();
var action = await handler!.ShouldHandleAsync(new Outcome<VoidResult>(new InvalidOperationException()), args);
var action = await handler!.ShouldHandleAsync<VoidResult>(new(ResilienceContext.Get(), new Outcome<VoidResult>(new InvalidOperationException()), args));
action.Should().NotBeNull();
(await action!(new Outcome<VoidResult>(new InvalidOperationException()), args)).Should().Be(VoidResult.Instance);
(await action!(new(ResilienceContext.Get(), new Outcome<VoidResult>(new InvalidOperationException()), args))).Should().Be(VoidResult.Instance);

action = await handler!.ShouldHandleAsync(new Outcome<VoidResult>(new ArgumentNullException()), args);
action = await handler!.ShouldHandleAsync<VoidResult>(new(ResilienceContext.Get(), new Outcome<VoidResult>(new ArgumentNullException()), args));
action.Should().BeNull();
}

Expand All @@ -105,18 +105,19 @@ public async Task ShouldHandleAsync_UnknownResultType_Null()
var handler = new FallbackHandler()
.SetFallback<int>(handler =>
{
handler.FallbackAction = (_, _) => default;
handler.ShouldHandle = (outcome, _) => new ValueTask<bool>(outcome.Exception is InvalidOperationException);
handler.FallbackAction = _ => default;
handler.ShouldHandle = args => new ValueTask<bool>(args.Exception is InvalidOperationException);
})
.SetFallback<string>(handler =>
{
handler.FallbackAction = (_, _) => default;
handler.ShouldHandle = (_, _) => PredicateResult.True;
handler.FallbackAction = _ => default;
handler.ShouldHandle = _ => PredicateResult.True;
})
.CreateHandler();

var args = new HandleFallbackArguments(ResilienceContext.Get());
var action = await handler!.ShouldHandleAsync(new Outcome<double>(new InvalidOperationException()), args);
var context = ResilienceContext.Get();
var args = new HandleFallbackArguments();
var action = await handler!.ShouldHandleAsync<double>(new(context, new Outcome<double>(new InvalidOperationException()), args));
action.Should().BeNull();
}
}
Loading

0 comments on commit 88d8612

Please sign in to comment.