public async Task <TResult> ExecuteAsync <TResult>( RandomSourceAsyncFunc <TSource, TResult> taskFunc, ShouldRetryPredicate shouldRetry, OnError onError = null) { for (var attemptCount = 1; ; attemptCount++) { var item = _chooseRandomly(); try { var result = await taskFunc(item, attemptCount); _updateWeight(item, true); return(result); } catch (Exception e) { onError?.Invoke(e, attemptCount); _updateWeight(item, false); if (!shouldRetry(attemptCount, e)) { throw; } } } }
public async Task <IReadOnlyList <RetryActionResult <TSource, TResult> > > ExecuteAsyncWithDiag <TResult>( RandomSourceAsyncFunc <TSource, TResult> taskFunc, ShouldRetryPredicate shouldRetry, OnError onError = null) { var stopwatch = new Stopwatch(); var results = new List <RetryActionResult <TSource, TResult> >(); for (var attemptCount = 1; ; attemptCount++) { var item = _chooseRandomly(); try { stopwatch.Restart(); var result = await taskFunc(item, attemptCount).ConfigureAwait(false); _updateWeight(item, true); results.Add(new RetryActionResult <TSource, TResult>( item, result, stopwatch.Elapsed, null, attemptCount)); break; } catch (Exception e) { results.Add(new RetryActionResult <TSource, TResult>( item, default(TResult), stopwatch.Elapsed, e, attemptCount)); _updateWeight(item, false); var isFailed = !shouldRetry(attemptCount, e); if (isFailed) { break; } } } return(results); }
public static Task <IReadOnlyList <RetryActionResult <TSource, TResult> > > ExecuteAsyncWithDiag <TSource, TResult>( this IResourceManager <TSource> mgr, RandomSourceAsyncFunc <TSource, TResult> taskFunc, ShouldRetryPredicate shouldRetry, OnError onError = null) { var retryAction = new RetryAction <TSource>(mgr.SelectRandomly, mgr.UpdateWeight); return(retryAction.ExecuteAsyncWithDiag(taskFunc, shouldRetry, onError)); }