Browse Source

Extract Policies to ResilientHttpClientFactory

pull/223/head
Ramón Tomás 7 years ago
parent
commit
4182750aad
2 changed files with 44 additions and 48 deletions
  1. +5
    -43
      src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs
  2. +39
    -5
      src/Web/WebMVC/Infrastructure/ResilientHttpClientFactory.cs

+ 5
- 43
src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs View File

@ -22,12 +22,14 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
{
private readonly HttpClient _client;
private readonly ILogger<ResilientHttpClient> _logger;
private readonly Func<string, IEnumerable<Policy>> _policyCreator;
private ConcurrentDictionary<string, PolicyWrap> _policyWrappers;
public ResilientHttpClient(ILogger<ResilientHttpClient> logger)
public ResilientHttpClient(Func<string, IEnumerable<Policy>> policyCreator, ILogger<ResilientHttpClient> logger)
{
_client = new HttpClient();
_logger = logger;
_policyCreator = policyCreator;
_policyWrappers = new ConcurrentDictionary<string, PolicyWrap>();
}
@ -130,7 +132,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
if (!_policyWrappers.TryGetValue(normalizedOrigin, out PolicyWrap policyWrap))
{
policyWrap = Policy.Wrap(CreatePolicies());
policyWrap = Policy.Wrap(_policyCreator(normalizedOrigin).ToArray());
_policyWrappers.TryAdd(normalizedOrigin, policyWrap);
}
@ -152,46 +154,6 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
var origin = $"{url.Scheme}://{url.DnsSafeHost}:{url.Port}";
return origin;
}
private Policy[] CreatePolicies()
{
return new Policy[]
{
Policy.Handle<HttpRequestException>()
.WaitAndRetry(
// number of retries
6,
// exponential backofff
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
// on retry
(exception, timeSpan, retryCount, context) =>
{
var msg = $"Retry {retryCount} implemented with Polly's RetryPolicy " +
$"of {context.PolicyKey} " +
$"at {context.ExecutionKey}, " +
$"due to: {exception}.";
_logger.LogWarning(msg);
_logger.LogDebug(msg);
}),
Policy.Handle<HttpRequestException>()
.CircuitBreaker(
// number of exceptions before breaking circuit
5,
// 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");
})
};
}
}
}
}

+ 39
- 5
src/Web/WebMVC/Infrastructure/ResilientHttpClientFactory.cs View File

@ -1,10 +1,7 @@
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Polly;
using System;
using System.Net.Http;
namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
@ -17,6 +14,43 @@ namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
=>_logger = logger;
public ResilientHttpClient CreateResilientHttpClient()
=> new ResilientHttpClient(_logger);
=> new ResilientHttpClient((origin) => CreatePolicies(), _logger);
private Policy[] CreatePolicies()
=> new Policy[]
{
Policy.Handle<HttpRequestException>()
.WaitAndRetry(
// number of retries
6,
// exponential backofff
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
// on retry
(exception, timeSpan, retryCount, context) =>
{
var msg = $"Retry {retryCount} implemented with Polly's RetryPolicy " +
$"of {context.PolicyKey} " +
$"at {context.ExecutionKey}, " +
$"due to: {exception}.";
_logger.LogWarning(msg);
_logger.LogDebug(msg);
}),
Policy.Handle<HttpRequestException>()
.CircuitBreaker(
// number of exceptions before breaking circuit
5,
// 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");
})
};
}
}

Loading…
Cancel
Save