Skip to content

Commit

Permalink
Merge pull request #108 from reisenberger/AsyncOnRetryDelegate
Browse files Browse the repository at this point in the history
Support async onRetry delegates on async retry policies
  • Loading branch information
joelhulen committed May 26, 2016
2 parents d61385b + 7bc9164 commit babdc3b
Show file tree
Hide file tree
Showing 18 changed files with 596 additions and 46 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 4.2.1

- Allowed async onRetry delegates to async retry policies. Thanks to [@reisenberger](https://github.com/reisenberger)


## 4.2.0

- Add AdvancedCircuitBreaker. Thanks to [@reisenberger](https://github.com/reisenberger) and [@kristianhald](https://github.com/kristianhald)
Expand Down
2 changes: 1 addition & 1 deletion GitVersionConfig.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
next-version: 4.2.0
next-version: 4.2.1
26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ Policy
.Handle<DivideByZeroException>()
.WaitAndRetry(new[]
{
1.Seconds(),
2.Seconds(),
3.Seconds()
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
}, (exception, timeSpan) => {
// do something
});
Expand All @@ -136,9 +136,9 @@ Policy
.Handle<DivideByZeroException>()
.WaitAndRetry(new[]
{
1.Seconds(),
2.Seconds(),
3.Seconds()
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
}, (exception, timeSpan, context) => {
// do something
});
Expand Down Expand Up @@ -208,6 +208,8 @@ Policy
});
```

For further information on the operation of retry policies, see also the [wiki](https://github.com/App-vNext/Polly/wiki/Retry).

### Circuit Breaker ###
```csharp
// Break the circuit after the specified number of exceptions
Expand Down Expand Up @@ -250,9 +252,10 @@ breaker.Isolate();
// Reset the breaker to closed state, to start accepting actions again.
breaker.Reset();


```

For further information on the operation of circuit breaker, see also the [wiki](https://github.com/App-vNext/Polly/wiki/Circuit-Breaker).

### Advanced Circuit Breaker ###
```csharp
// Break the circuit if, within any period of duration samplingDuration,
Expand All @@ -276,7 +279,7 @@ Policy
// available as described for CircuitBreaker above.
```

For further information on the operation of the Advanced Circuit Breaker, see the [Wiki](https://github.com/App-vNext/Polly/wiki/Advanced-Circuit-Breaker)
For further information on the operation of Advanced Circuit Breaker, see the [Wiki](https://github.com/App-vNext/Polly/wiki/Advanced-Circuit-Breaker)

For more information on the Circuit Breaker pattern in general see:
* [Making the Netflix API More Resilient](http://techblog.netflix.com/2011/12/making-netflix-api-more-resilient.html)
Expand Down Expand Up @@ -363,7 +366,9 @@ You can use Polly with asynchronous functions by using the asynchronous methods
* `RetryAsync`
* `RetryForeverAsync`
* `WaitAndRetryAsync`
* `WaitAndRetryForeverAsync`
* `CircuitBreakerAsync`
* `AdvancedCircuitBreakerAsync`
* `ExecuteAsync`
* `ExecuteAndCaptureAsync`

Expand All @@ -372,7 +377,9 @@ In place of their synchronous counterparts
* `Retry`
* `RetryForever`
* `WaitAndRetry`
* `WaitAndRetryForever`
* `CircuitBreaker`
* `AdvancedCircuitBreaker`
* `Execute`
* `ExecuteAndCapture`

Expand Down Expand Up @@ -437,6 +444,9 @@ Acknowledgements
* [@reisenberger](https://github.com/reisenberger) - Added async support for ContextualPolicy
* [@reisenberger](https://github.com/reisenberger) - Added ContextualPolicy support for circuit-breaker
* [@reisenberger](https://github.com/reisenberger) - Extended circuit-breaker for public monitoring and control
* [@reisenberger](https://github.com/reisenberger) - Added ExecuteAndCapture support with arbitrary context data
* [@kristianhald](https://github.com/kristianhald) and [@reisenberger](https://github.com/reisenberger) - Added AdvancedCircuitBreaker
* [@reisenberger](https://github.com/reisenberger) - Allowed async onRetry delegates to async retry policies

Sample Projects
=
Expand Down
2 changes: 1 addition & 1 deletion src/Polly.Shared/Retry/RetryPolicyState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public RetryPolicyState(Action<Exception, Context> onRetry, Context context)
}

public RetryPolicyState(Action<Exception> onRetry) :
this((exception, context) => onRetry(exception), null)
this((exception, context) => onRetry(exception), Context.Empty)
{
}

Expand Down
19 changes: 15 additions & 4 deletions src/Polly.Shared/Retry/RetryPolicyStateAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,23 @@ namespace Polly.Retry
{
internal partial class RetryPolicyState : IRetryPolicyState
{
static readonly Task<bool> Done = Task.FromResult(true);
private readonly Func<Exception, Context, Task> _onRetryAsync;

public Task<bool> CanRetryAsync(Exception ex, CancellationToken ct, bool continueOnCapturedContext)
public RetryPolicyState(Func<Exception, Context, Task> onRetryAsync, Context context)
{
_onRetry(ex, _context);
return Done;
_onRetryAsync = onRetryAsync;
_context = context;
}

public RetryPolicyState(Func<Exception, Task> onRetryAsync) :
this((exception, context) => onRetryAsync(exception), Context.Empty)
{
}

public async Task<bool> CanRetryAsync(Exception ex, CancellationToken ct, bool continueOnCapturedContext)
{
await _onRetryAsync(ex, _context).ConfigureAwait(continueOnCapturedContext);
return true;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Polly.Shared/Retry/RetryPolicyStateWithCount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public RetryPolicyStateWithCount(int retryCount, Action<Exception, int, Context>
}

public RetryPolicyStateWithCount(int retryCount, Action<Exception, int> onRetry) :
this(retryCount, (exception, i, context) => onRetry(exception, i), null)
this(retryCount, (exception, i, context) => onRetry(exception, i), Context.Empty)
{
}

Expand Down
26 changes: 24 additions & 2 deletions src/Polly.Shared/Retry/RetryPolicyStateWithCountAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,31 @@ namespace Polly.Retry
{
internal partial class RetryPolicyStateWithCount : IRetryPolicyState
{
public Task<bool> CanRetryAsync(Exception ex, CancellationToken ct, bool continueOnCapturedContext)
private readonly Func<Exception, int, Context, Task> _onRetryAsync;

public RetryPolicyStateWithCount(int retryCount, Func<Exception, int, Context, Task> onRetryAsync, Context context)
{
return Task.FromResult(CanRetry(ex));
_retryCount = retryCount;
_onRetryAsync = onRetryAsync;
_context = context;
}

public RetryPolicyStateWithCount(int retryCount, Func<Exception, int, Task> onRetryAsync) :
this(retryCount, (exception, i, context) => onRetryAsync(exception, i), Context.Empty)
{
}

public async Task<bool> CanRetryAsync(Exception ex, CancellationToken ct, bool continueOnCapturedContext)
{
_errorCount += 1;

var shouldRetry = _errorCount <= _retryCount;
if (shouldRetry)
{
await _onRetryAsync(ex, _errorCount, _context).ConfigureAwait(continueOnCapturedContext);
}

return shouldRetry;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Polly.Shared/Retry/RetryPolicyStateWithSleep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public RetryPolicyStateWithSleep(IEnumerable<TimeSpan> sleepDurations, Action<Ex
}

public RetryPolicyStateWithSleep(IEnumerable<TimeSpan> sleepDurations, Action<Exception, TimeSpan> onRetry) :
this(sleepDurations, (exception, span, context) => onRetry(exception, span), null)
this(sleepDurations, (exception, span, context) => onRetry(exception, span), Context.Empty)
{
}

Expand Down
18 changes: 17 additions & 1 deletion src/Polly.Shared/Retry/RetryPolicyStateWithSleepAsync.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#if SUPPORTS_ASYNC

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Polly.Utilities;
Expand All @@ -9,12 +10,27 @@ namespace Polly.Retry
{
internal partial class RetryPolicyStateWithSleep : IRetryPolicyState
{
private readonly Func<Exception, TimeSpan, Context, Task> _onRetryAsync;


public RetryPolicyStateWithSleep(IEnumerable<TimeSpan> sleepDurations, Func<Exception, TimeSpan, Context, Task> onRetryAsync, Context context)
{
_onRetryAsync = onRetryAsync;
_context = context;
_sleepDurationsEnumerator = sleepDurations.GetEnumerator();
}

public RetryPolicyStateWithSleep(IEnumerable<TimeSpan> sleepDurations, Func<Exception, TimeSpan, Task> onRetryAsync) :
this(sleepDurations, (exception, span, context) => onRetryAsync(exception, span), Context.Empty)
{
}

public async Task<bool> CanRetryAsync(Exception ex, CancellationToken cancellationToken, bool continueOnCapturedContext)
{
if (!_sleepDurationsEnumerator.MoveNext()) return false;

var currentTimeSpan = _sleepDurationsEnumerator.Current;
_onRetry(ex, currentTimeSpan, _context);
await _onRetryAsync(ex, currentTimeSpan, _context).ConfigureAwait(continueOnCapturedContext);

await SystemClock.SleepAsync(currentTimeSpan, cancellationToken).ConfigureAwait(continueOnCapturedContext);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public RetryPolicyStateWithSleepDurationProvider(Func<int, TimeSpan> sleepDurati
}

public RetryPolicyStateWithSleepDurationProvider(Func<int, TimeSpan> sleepDurationProvider, Action<Exception, TimeSpan> onRetry) :
this(sleepDurationProvider, (exception, timespan, context) => onRetry(exception, timespan), null)
this(sleepDurationProvider, (exception, timespan, context) => onRetry(exception, timespan), Context.Empty)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ namespace Polly.Retry
{
internal partial class RetryPolicyStateWithSleepDurationProvider : IRetryPolicyState
{
private readonly Func<Exception, TimeSpan, Context, Task> _onRetryAsync;

public RetryPolicyStateWithSleepDurationProvider(Func<int, TimeSpan> sleepDurationProvider, Func<Exception, TimeSpan, Context, Task> onRetryAsync, Context context)
{
this._sleepDurationProvider = sleepDurationProvider;
_onRetryAsync = onRetryAsync;
_context = context;
}

public RetryPolicyStateWithSleepDurationProvider(Func<int, TimeSpan> sleepDurationProvider, Func<Exception, TimeSpan, Task> onRetryAsync) :
this(sleepDurationProvider, (exception, timespan, context) => onRetryAsync(exception, timespan), Context.Empty)
{
}

public async Task<bool> CanRetryAsync(Exception ex, CancellationToken cancellationToken, bool continueOnCapturedContext)
{
if (_errorCount < int.MaxValue)
Expand All @@ -17,7 +31,7 @@ public async Task<bool> CanRetryAsync(Exception ex, CancellationToken cancellati
}

var currentTimeSpan = _sleepDurationProvider(_errorCount);
_onRetry(ex, currentTimeSpan, _context);
await _onRetryAsync(ex, currentTimeSpan, _context).ConfigureAwait(continueOnCapturedContext);

await SystemClock.SleepAsync(currentTimeSpan, cancellationToken).ConfigureAwait(continueOnCapturedContext);

Expand Down
4 changes: 2 additions & 2 deletions src/Polly.Shared/RetrySyntax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public static RetryPolicy WaitAndRetry(this PolicyBuilder policyBuilder, int re
/// <returns>The policy instance.</returns>
/// <exception cref="System.ArgumentOutOfRangeException">retryCount;Value must be greater than or equal to zero.</exception>
/// <exception cref="System.ArgumentNullException">
/// timeSpanProvider
/// sleepDurationProvider
/// or
/// onRetry
/// </exception>
Expand Down Expand Up @@ -224,7 +224,7 @@ public static RetryPolicy WaitAndRetry(this PolicyBuilder policyBuilder, int re
/// <returns>The policy instance.</returns>
/// <exception cref="System.ArgumentOutOfRangeException">retryCount;Value must be greater than or equal to zero.</exception>
/// <exception cref="System.ArgumentNullException">
/// timeSpanProvider
/// sleepDurationProvider
/// or
/// onRetry
/// </exception>
Expand Down
Loading

0 comments on commit babdc3b

Please sign in to comment.