private async Task <T> HttpInvoker <T>(string origin, Func <Task <T> > action) { var normalizedOrigin = NormalizeOrigin(origin); if (!_pocilyWrappers.TryGetValue(normalizedOrigin, out PolicyWrap policyWrap)) { policyWrap = PolicyWrap.WrapAsync(_policyCreator(normalizedOrigin).ToArray()); _pocilyWrappers.TryAdd(normalizedOrigin, policyWrap); } // Executes the action applying all // the policies defined in the wrapper return(await policyWrap.ExecuteAsync(action, new Context(normalizedOrigin))); }
public async Task <TResult> TryExecuteAsync <TResult>(Func <Task <TResult> > actionToPerform, Func <Exception, bool> isRetryableException, int retryCount = 5, TimeSpan?retryAttempt = null, bool isLinearRetry = false) { var retryAttemptInSeconds = retryAttempt.HasValue ? retryAttempt.Value.Seconds : _defaultRetryAttemptInSeconds; var policies = new Policy[] { Policy.Handle <Exception>(isRetryableException) .WaitAndRetryAsync( // number of retries retryCount, // backoff retryTimeSpan => isLinearRetry ? TimeSpan.FromSeconds(retryAttemptInSeconds) : TimeSpan.FromSeconds(Math.Pow(2, retryAttemptInSeconds)), // on retry (exception, timeSpan, currentRetryCount, context) => { var msg = $"Retry ({currentRetryCount} of {retryCount}) due to: {exception}."; _logger.LogWarning(msg); _logger.LogDebug(msg); }), Policy.Handle <Exception>(isRetryableException) .CircuitBreakerAsync( // number of exceptions before breaking circuit _exceptionsAllowedBeforeBreaking, // time circuit opened before retry TimeSpan.FromMinutes(1), (exception, duration) => { // on circuit opened _logger.LogTrace("Circuit breaker opened"); }, () => { // on circuit closed _logger.LogTrace("Circuit breaker reset"); }) }; var policyWrap = PolicyWrap.WrapAsync(policies); return(await policyWrap.ExecuteAsync <TResult>(actionToPerform)); }