Skip to content

Commit

Permalink
Add CancellationToken support to retry async methods. Fix typos in do…
Browse files Browse the repository at this point in the history
…cuments.
  • Loading branch information
Dixin committed Jan 25, 2024
1 parent b0e361c commit d6a2e91
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 29 deletions.
16 changes: 10 additions & 6 deletions Source/TransientFaultHandling.Core/Retry.Execute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public static partial class Retry
/// <summary>
/// Repetitively executes the specified action while it satisfies the specified retry strategy.
/// </summary>
/// <typeparam name="TResult">he type of result expected from the executable action.</typeparam>
/// <typeparam name="TResult">The type of result expected from the executable action.</typeparam>
/// <param name="func">A delegate that represents the executable action that returns the result of type <typeparamref name="TResult" />.</param>
/// <param name="retryStrategy">The retry strategy.</param>
/// <param name="isTransient">The predicate function to detect whether the specified exception is transient.</param>
Expand Down Expand Up @@ -48,22 +48,24 @@ public static partial class Retry
/// <summary>
/// Repeatedly executes the specified asynchronous function while it satisfies the current retry policy.
/// </summary>
/// <typeparam name="TResult">he type of result expected from the executable asynchronous function.</typeparam>
/// <typeparam name="TResult">The type of result expected from the executable asynchronous function.</typeparam>
/// <param name="func">A asynchronous function that returns a started task (also known as "hot" task).</param>
/// <param name="retryStrategy">The retry strategy.</param>
/// <param name="isTransient">The predicate function to detect whether the specified exception is transient.</param>
/// <param name="retryingHandler">The callback function that will be invoked whenever a retry condition is encountered.</param>
/// <param name="cancellationToken">The token used to cancel the retry operation. This token does not cancel the execution of the asynchronous task.</param>
/// <returns>Returns a task that will run to completion if the original task completes successfully (either the first time or after retrying transient failures). If the task fails with a non-transient error or the retry limit is reached, the returned task will transition to a faulted state and the exception must be observed.</returns>
/// <exception cref="ArgumentNullException">func</exception>
public static Task<TResult> ExecuteAsync<TResult>(
Func<Task<TResult>> func,
RetryStrategy? retryStrategy = null,
Func<Exception, bool>? isTransient = null,
EventHandler<RetryingEventArgs>? retryingHandler = null)
EventHandler<RetryingEventArgs>? retryingHandler = null,
CancellationToken cancellationToken = default)
{
func.NotNull();

return CreateRetryPolicy(retryStrategy, isTransient, retryingHandler).ExecuteAsync(func);
return CreateRetryPolicy(retryStrategy, isTransient, retryingHandler).ExecuteAsync(func, cancellationToken);
}

/// <summary>
Expand All @@ -73,16 +75,18 @@ public static partial class Retry
/// <param name="retryStrategy">The retry strategy.</param>
/// <param name="isTransient">The predicate function to detect whether the specified exception is transient.</param>
/// <param name="retryingHandler">The callback function that will be invoked whenever a retry condition is encountered.</param>
/// <param name="cancellationToken">The token used to cancel the retry operation. This token does not cancel the execution of the asynchronous task.</param>
/// <returns>Returns a task that will run to completion if the original task completes successfully (either the first time or after retrying transient failures). If the task fails with a non-transient error or the retry limit is reached, the returned task will transition to a faulted state and the exception must be observed.</returns>
/// <exception cref="ArgumentNullException">func</exception>
public static Task ExecuteAsync(
Func<Task> func,
RetryStrategy? retryStrategy = null,
Func<Exception, bool>? isTransient = null,
EventHandler<RetryingEventArgs>? retryingHandler = null)
EventHandler<RetryingEventArgs>? retryingHandler = null,
CancellationToken cancellationToken = default)
{
func.NotNull();

return CreateRetryPolicy(retryStrategy, isTransient, retryingHandler).ExecuteAsync(func);
return CreateRetryPolicy(retryStrategy, isTransient, retryingHandler).ExecuteAsync(func, cancellationToken);
}
}
28 changes: 17 additions & 11 deletions Source/TransientFaultHandling.Core/Retry.ExponentialBackoff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public static partial class Retry
/// <summary>
/// Repetitively executes the specified action while it satisfies the specified retry strategy.
/// </summary>
/// <typeparam name="TResult">he type of result expected from the executable action.</typeparam>
/// <typeparam name="TResult">The type of result expected from the executable action.</typeparam>
/// <param name="func">A delegate that represents the executable action that returns the result of type <typeparamref name="TResult" />.</param>
/// <param name="retryCount">The number of retry attempts.</param>
/// <param name="isTransient">The predicate function to detect whether the specified exception is transient.</param>
Expand Down Expand Up @@ -61,7 +61,7 @@ public static partial class Retry
/// <summary>
/// Repeatedly executes the specified asynchronous function while it satisfies the current retry policy.
/// </summary>
/// <typeparam name="TResult">he type of result expected from the executable asynchronous function.</typeparam>
/// <typeparam name="TResult">The type of result expected from the executable asynchronous function.</typeparam>
/// <param name="func">A asynchronous function that returns a started task (also known as "hot" task).</param>
/// <param name="retryCount">The number of retry attempts.</param>
/// <param name="isTransient">The predicate function to detect whether the specified exception is transient.</param>
Expand All @@ -70,6 +70,7 @@ public static partial class Retry
/// <param name="maxBackoff">The maximum backoff time.</param>
/// <param name="deltaBackoff">The value that will be used to calculate a random delta in the exponential delay between retries.</param>
/// <param name="firstFastRetry">true to immediately retry in the first attempt; otherwise, false. The subsequent retries will remain subject to the configured retry interval.</param>
/// <param name="cancellationToken">The token used to cancel the retry operation. This token does not cancel the execution of the asynchronous task.</param>
/// <returns>Returns a task that will run to completion if the original task completes successfully (either the first time or after retrying transient failures). If the task fails with a non-transient error or the retry limit is reached, the returned task will transition to a faulted state and the exception must be observed.</returns>
/// <exception cref="ArgumentNullException">func</exception>
public static Task<TResult> ExponentialBackoffAsync<TResult>(
Expand All @@ -80,12 +81,14 @@ public static partial class Retry
TimeSpan? minBackoff = null,
TimeSpan? maxBackoff = null,
TimeSpan? deltaBackoff = null,
bool? firstFastRetry = null) =>
bool? firstFastRetry = null,
CancellationToken cancellationToken = default) =>
ExecuteAsync(
func.NotNull(),
WithExponentialBackoff(retryCount, minBackoff, maxBackoff, deltaBackoff, firstFastRetry),
isTransient,
retryingHandler);
retryingHandler,
cancellationToken);

/// <summary>
/// Repeatedly executes the specified asynchronous function while it satisfies the current retry policy.
Expand All @@ -98,6 +101,7 @@ public static partial class Retry
/// <param name="maxBackoff">The maximum backoff time.</param>
/// <param name="deltaBackoff">The value that will be used to calculate a random delta in the exponential delay between retries.</param>
/// <param name="firstFastRetry">true to immediately retry in the first attempt; otherwise, false. The subsequent retries will remain subject to the configured retry interval.</param>
/// <param name="cancellationToken">The token used to cancel the retry operation. This token does not cancel the execution of the asynchronous task.</param>
/// <returns>Returns a task that will run to completion if the original task completes successfully (either the first time or after retrying transient failures). If the task fails with a non-transient error or the retry limit is reached, the returned task will transition to a faulted state and the exception must be observed.</returns>
/// <exception cref="ArgumentNullException">func</exception>
public static Task ExponentialBackoffAsync(
Expand All @@ -108,12 +112,14 @@ public static partial class Retry
TimeSpan? minBackoff = null,
TimeSpan? maxBackoff = null,
TimeSpan? deltaBackoff = null,
bool? firstFastRetry = null) =>
bool? firstFastRetry = null,
CancellationToken cancellationToken = default) =>
ExecuteAsync(
func.NotNull(),
WithExponentialBackoff(retryCount, minBackoff, maxBackoff, deltaBackoff, firstFastRetry),
isTransient,
retryingHandler);
retryingHandler,
cancellationToken);

/// <summary>
/// Create a new instance of the <see cref="T:Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.ExponentialBackoff" /> class.
Expand All @@ -126,11 +132,11 @@ public static partial class Retry
/// <param name="name">The name of the retry strategy.</param>
/// <returns>A new instance of the <see cref="T:Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.ExponentialBackoff" /> class.</returns>
public static ExponentialBackoff WithExponentialBackoff(
int? retryCount = null,
TimeSpan? minBackoff = null,
TimeSpan? maxBackoff = null,
TimeSpan? deltaBackoff = null,
bool? firstFastRetry = null,
int? retryCount = null,
TimeSpan? minBackoff = null,
TimeSpan? maxBackoff = null,
TimeSpan? deltaBackoff = null,
bool? firstFastRetry = null,
string? name = null) => new(
name,
retryCount ?? RetryStrategy.DefaultClientRetryCount,
Expand Down
18 changes: 12 additions & 6 deletions Source/TransientFaultHandling.Core/Retry.FixedInterval.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public static partial class Retry
/// <summary>
/// Repetitively executes the specified action while it satisfies the specified retry strategy.
/// </summary>
/// <typeparam name="TResult">he type of result expected from the executable action.</typeparam>
/// <typeparam name="TResult">The type of result expected from the executable action.</typeparam>
/// <param name="func">A delegate that represents the executable action that returns the result of type <typeparamref name="TResult" />.</param>
/// <param name="retryCount">The number of retry attempts.</param>
/// <param name="isTransient">The predicate function to detect whether the specified exception is transient.</param>
Expand Down Expand Up @@ -53,13 +53,14 @@ public static partial class Retry
/// <summary>
/// Repeatedly executes the specified asynchronous function while it satisfies the current retry policy.
/// </summary>
/// <typeparam name="TResult">he type of result expected from the executable asynchronous function.</typeparam>
/// <typeparam name="TResult">The type of result expected from the executable asynchronous function.</typeparam>
/// <param name="func">A asynchronous function that returns a started task (also known as "hot" task).</param>
/// <param name="retryCount">The number of retry attempts.</param>
/// <param name="isTransient">The predicate function to detect whether the specified exception is transient.</param>
/// <param name="retryingHandler">The callback function that will be invoked whenever a retry condition is encountered.</param>
/// <param name="retryInterval">The time interval between retries.</param>
/// <param name="firstFastRetry">true to immediately retry in the first attempt; otherwise, false. The subsequent retries will remain subject to the configured retry interval.</param>
/// <param name="cancellationToken">The token used to cancel the retry operation. This token does not cancel the execution of the asynchronous task.</param>
/// <returns>Returns a task that will run to completion if the original task completes successfully (either the first time or after retrying transient failures). If the task fails with a non-transient error or the retry limit is reached, the returned task will transition to a faulted state and the exception must be observed.</returns>
/// <exception cref="ArgumentNullException">func</exception>
public static Task<TResult> FixedIntervalAsync<TResult>(
Expand All @@ -68,12 +69,14 @@ public static partial class Retry
Func<Exception, bool>? isTransient = null,
EventHandler<RetryingEventArgs>? retryingHandler = null,
TimeSpan? retryInterval = null,
bool? firstFastRetry = null) =>
bool? firstFastRetry = null,
CancellationToken cancellationToken = default) =>
ExecuteAsync(
func.NotNull(),
WithFixedInterval(retryCount, retryInterval, firstFastRetry),
isTransient,
retryingHandler);
retryingHandler,
cancellationToken);

/// <summary>
/// Repeatedly executes the specified asynchronous function while it satisfies the current retry policy.
Expand All @@ -84,6 +87,7 @@ public static partial class Retry
/// <param name="retryingHandler">The callback function that will be invoked whenever a retry condition is encountered.</param>
/// <param name="retryInterval">The time interval between retries.</param>
/// <param name="firstFastRetry">true to immediately retry in the first attempt; otherwise, false. The subsequent retries will remain subject to the configured retry interval.</param>
/// <param name="cancellationToken">The token used to cancel the retry operation. This token does not cancel the execution of the asynchronous task.</param>
/// <returns>Returns a task that will run to completion if the original task completes successfully (either the first time or after retrying transient failures). If the task fails with a non-transient error or the retry limit is reached, the returned task will transition to a faulted state and the exception must be observed.</returns>
/// <exception cref="ArgumentNullException">func</exception>
public static Task FixedIntervalAsync(
Expand All @@ -92,12 +96,14 @@ public static partial class Retry
Func<Exception, bool>? isTransient = null,
EventHandler<RetryingEventArgs>? retryingHandler = null,
TimeSpan? retryInterval = null,
bool? firstFastRetry = null) =>
bool? firstFastRetry = null,
CancellationToken cancellationToken = default) =>
ExecuteAsync(
func.NotNull(),
WithFixedInterval(retryCount, retryInterval, firstFastRetry),
isTransient,
retryingHandler);
retryingHandler,
cancellationToken);

/// <summary>
/// Create a new instance of the <see cref="T:Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.FixedInterval" /> class.
Expand Down
Loading

0 comments on commit d6a2e91

Please sign in to comment.