diff --git a/src/Ocelot/Requester/HttpClientHttpRequester.cs b/src/Ocelot/Requester/HttpClientHttpRequester.cs index 0167ef6a..8056adeb 100644 --- a/src/Ocelot/Requester/HttpClientHttpRequester.cs +++ b/src/Ocelot/Requester/HttpClientHttpRequester.cs @@ -4,22 +4,58 @@ using System.Net.Http; using System.Threading.Tasks; using Ocelot.Errors; using Ocelot.Responses; +using Polly; +using Polly.Timeout; +using Polly.CircuitBreaker; +using Ocelot.Logging; namespace Ocelot.Requester { public class HttpClientHttpRequester : IHttpRequester { + private readonly IOcelotLogger _logger; + + public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory) + { + _logger = loggerFactory.CreateLogger(); + } + public async Task> GetResponse(Request.Request request) { + double timeoutvalue = 5000; + TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic; + + var timeoutPolicy = Policy + .TimeoutAsync(TimeSpan.FromMilliseconds(timeoutvalue), timeoutStrategy); + + var circuitBreakerPolicy = Policy + .Handle() + .Or() + .Or() + .CircuitBreakerAsync( + exceptionsAllowedBeforeBreaking: 4, + durationOfBreak: TimeSpan.FromSeconds(8), + onBreak: (ex, breakDelay) => + { + _logger.LogError(".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex); + }, + onReset: () => _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."), + onHalfOpen: () => _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.") + ); + using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer }) using (var httpClient = new HttpClient(handler)) { try { - var response = await httpClient.SendAsync(request.HttpRequestMessage); + // Retry the following call according to the policy - 3 times. + HttpResponseMessage response = await Policy.WrapAsync(circuitBreakerPolicy, timeoutPolicy).ExecuteAsync(() => + { + return httpClient.SendAsync(request.HttpRequestMessage); + }); return new OkResponse(response); } - catch (Exception exception) + catch (BrokenCircuitException exception) { return new ErrorResponse(new List diff --git a/src/Ocelot/project.json b/src/Ocelot/project.json index 85008568..6711d984 100644 --- a/src/Ocelot/project.json +++ b/src/Ocelot/project.json @@ -27,7 +27,8 @@ "Microsoft.NETCore.App": "1.1.0", "CacheManager.Core": "0.9.2", "CacheManager.Microsoft.Extensions.Configuration": "0.9.2", - "CacheManager.Microsoft.Extensions.Logging": "0.9.2" + "CacheManager.Microsoft.Extensions.Logging": "0.9.2", + "Polly": "5.0.3" }, "runtimes": { "win10-x64": {},