From a815a58808185eebbd411c425df63a020ea1d722 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 2 Oct 2023 11:38:04 +0200 Subject: [PATCH 01/10] #1712 Migrate to Polly 8.0 --- src/Ocelot.Provider.Polly/CircuitBreaker.cs | 9 +---- .../Ocelot.Provider.Polly.csproj | 2 +- .../OcelotBuilderExtensions.cs | 13 +++++-- .../PollyCircuitBreakingDelegatingHandler.cs | 8 +++- src/Ocelot.Provider.Polly/PollyQoSProvider.cs | 37 +++++++++---------- test/Ocelot.UnitTests/Ocelot.UnitTests.csproj | 2 +- 6 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/Ocelot.Provider.Polly/CircuitBreaker.cs b/src/Ocelot.Provider.Polly/CircuitBreaker.cs index ce2a89bf2..701abacac 100644 --- a/src/Ocelot.Provider.Polly/CircuitBreaker.cs +++ b/src/Ocelot.Provider.Polly/CircuitBreaker.cs @@ -4,16 +4,11 @@ namespace Ocelot.Provider.Polly { public class CircuitBreaker { - private readonly List _policies = new(); - public CircuitBreaker(params IAsyncPolicy[] policies) { - foreach (var policy in policies.Where(p => p != null)) - { - _policies.Add(policy); - } + Policies = policies.Where(p => p != null).ToArray(); } - public IAsyncPolicy[] Policies => _policies.ToArray(); + public IAsyncPolicy[] Policies { get; } } } diff --git a/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj b/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj index 4ffcb9eb6..78150d630 100644 --- a/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj +++ b/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj @@ -34,7 +34,7 @@ all - + diff --git a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs index 0d167f571..3821502a8 100644 --- a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs +++ b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs @@ -1,11 +1,18 @@ -using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; + +using Polly.CircuitBreaker; +using Polly.Timeout; + +using Microsoft.Extensions.DependencyInjection; + using Ocelot.Configuration; using Ocelot.DependencyInjection; using Ocelot.Errors; using Ocelot.Logging; using Ocelot.Requester; -using Polly.CircuitBreaker; -using Polly.Timeout; namespace Ocelot.Provider.Polly { diff --git a/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs b/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs index 9153b70ce..e1605cb27 100644 --- a/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs +++ b/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs @@ -1,5 +1,11 @@ +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + using Ocelot.Logging; using Ocelot.Provider.Polly.Interfaces; + using Polly; using Polly.CircuitBreaker; @@ -28,7 +34,7 @@ protected override async Task SendAsync(HttpRequestMessage return await base.SendAsync(request, cancellationToken); } - IAsyncPolicy policy = policies.Length > 1 + var policy = policies.Length > 1 ? Policy.WrapAsync(policies) : policies[0]; diff --git a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs index 420939de4..03bc36c1b 100644 --- a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs +++ b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs @@ -1,6 +1,10 @@ +using System; +using System.Net.Http; + using Ocelot.Configuration; using Ocelot.Logging; using Ocelot.Provider.Polly.Interfaces; + using Polly; using Polly.CircuitBreaker; using Polly.Timeout; @@ -9,28 +13,18 @@ namespace Ocelot.Provider.Polly { public class PollyQoSProvider : IPollyQoSProvider { - private readonly AsyncCircuitBreakerPolicy _circuitBreakerPolicy; - private readonly AsyncTimeoutPolicy _timeoutPolicy; - private readonly IOcelotLogger _logger; - - public PollyQoSProvider(AsyncCircuitBreakerPolicy circuitBreakerPolicy, AsyncTimeoutPolicy timeoutPolicy, IOcelotLogger logger) - { - _circuitBreakerPolicy = circuitBreakerPolicy; - _timeoutPolicy = timeoutPolicy; - _logger = logger; - } - public PollyQoSProvider(DownstreamRoute route, IOcelotLoggerFactory loggerFactory) { - _logger = loggerFactory.CreateLogger(); + AsyncCircuitBreakerPolicy circuitBreakerPolicy; + var logger = loggerFactory.CreateLogger(); _ = Enum.TryParse(route.QosOptions.TimeoutStrategy, out TimeoutStrategy strategy); - _timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(route.QosOptions.TimeoutValue), strategy); + var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(route.QosOptions.TimeoutValue), strategy); if (route.QosOptions.ExceptionsAllowedBeforeBreaking > 0) { - _circuitBreakerPolicy = Policy + circuitBreakerPolicy = Policy .Handle() .Or() .Or() @@ -39,25 +33,30 @@ public PollyQoSProvider(DownstreamRoute route, IOcelotLoggerFactory loggerFactor durationOfBreak: TimeSpan.FromMilliseconds(route.QosOptions.DurationOfBreak), onBreak: (ex, breakDelay) => { - _logger.LogError( + logger.LogError( ".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex); }, onReset: () => { - _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."); + logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."); }, onHalfOpen: () => { - _logger.LogDebug(".Breaker logging: Half-open; next call is a trial."); + logger.LogDebug(".Breaker logging: Half-open; next call is a trial."); } ); } else { - _circuitBreakerPolicy = null; + circuitBreakerPolicy = null; } - CircuitBreaker = new CircuitBreaker(_circuitBreakerPolicy, _timeoutPolicy); + CircuitBreaker = new CircuitBreaker(circuitBreakerPolicy, timeoutPolicy); + } + + [Obsolete("do not use: it does nothing")] + public PollyQoSProvider(AsyncCircuitBreakerPolicy circuitBreakerPolicy, AsyncTimeoutPolicy timeoutPolicy, IOcelotLogger logger) + { } public CircuitBreaker CircuitBreaker { get; } diff --git a/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj b/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj index 0c9fe46f7..8f0638fc5 100644 --- a/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj +++ b/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj @@ -88,7 +88,7 @@ - + From a86a372828df038d0f0ace1f02167a2b4632e7be Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 2 Oct 2023 14:23:15 +0200 Subject: [PATCH 02/10] code review post merge --- src/Ocelot.Provider.Polly/CircuitBreaker.cs | 2 -- .../OcelotBuilderExtensions.cs | 13 ++++--------- .../PollyCircuitBreakingDelegatingHandler.cs | 6 ------ src/Ocelot.Provider.Polly/PollyQoSProvider.cs | 6 +----- src/Ocelot.Provider.Polly/Usings.cs | 2 -- 5 files changed, 5 insertions(+), 24 deletions(-) diff --git a/src/Ocelot.Provider.Polly/CircuitBreaker.cs b/src/Ocelot.Provider.Polly/CircuitBreaker.cs index 701abacac..c9be6d924 100644 --- a/src/Ocelot.Provider.Polly/CircuitBreaker.cs +++ b/src/Ocelot.Provider.Polly/CircuitBreaker.cs @@ -1,5 +1,3 @@ -using Polly; - namespace Ocelot.Provider.Polly { public class CircuitBreaker diff --git a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs index 3821502a8..99e7bf209 100644 --- a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs +++ b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs @@ -1,18 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; - -using Polly.CircuitBreaker; -using Polly.Timeout; - -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Ocelot.Configuration; using Ocelot.DependencyInjection; using Ocelot.Errors; using Ocelot.Logging; using Ocelot.Requester; + +using Polly.CircuitBreaker; +using Polly.Timeout; namespace Ocelot.Provider.Polly { diff --git a/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs b/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs index e1605cb27..0a0b3909e 100644 --- a/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs +++ b/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs @@ -1,12 +1,6 @@ -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - using Ocelot.Logging; using Ocelot.Provider.Polly.Interfaces; -using Polly; using Polly.CircuitBreaker; namespace Ocelot.Provider.Polly diff --git a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs index 03bc36c1b..aa1959613 100644 --- a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs +++ b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs @@ -1,11 +1,7 @@ -using System; -using System.Net.Http; - using Ocelot.Configuration; using Ocelot.Logging; using Ocelot.Provider.Polly.Interfaces; - -using Polly; + using Polly.CircuitBreaker; using Polly.Timeout; diff --git a/src/Ocelot.Provider.Polly/Usings.cs b/src/Ocelot.Provider.Polly/Usings.cs index 0cc4c6d4f..fb5c12dc6 100644 --- a/src/Ocelot.Provider.Polly/Usings.cs +++ b/src/Ocelot.Provider.Polly/Usings.cs @@ -1,12 +1,10 @@ // Default Microsoft.NET.Sdk namespaces global using System; global using System.Collections.Generic; -global using System.IO; global using System.Linq; global using System.Net.Http; global using System.Threading; global using System.Threading.Tasks; // Project extra global namespaces -global using Ocelot; global using Polly; From de664956d6c26f9637657c17a1ac8ebaeabe11e4 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Oct 2023 14:30:52 +0200 Subject: [PATCH 03/10] post PR --- src/Ocelot.Provider.Polly/PollyQoSProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs index aa1959613..52a29568d 100644 --- a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs +++ b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs @@ -50,7 +50,7 @@ public PollyQoSProvider(DownstreamRoute route, IOcelotLoggerFactory loggerFactor CircuitBreaker = new CircuitBreaker(circuitBreakerPolicy, timeoutPolicy); } - [Obsolete("do not use: it does nothing")] + [Obsolete("Use the constructor PollyQoSProvider(DownstreamRoute route, IOcelotLoggerFactory loggerFactory)")] public PollyQoSProvider(AsyncCircuitBreakerPolicy circuitBreakerPolicy, AsyncTimeoutPolicy timeoutPolicy, IOcelotLogger logger) { } From 4d9acad1749abd15b9fa5973eb73d38f69fb5d75 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 2 Oct 2023 11:38:04 +0200 Subject: [PATCH 04/10] #1712 Migrate to Polly 8.0 --- .../OcelotBuilderExtensions.cs | 13 +++++++++---- .../PollyCircuitBreakingDelegatingHandler.cs | 6 ++++++ src/Ocelot.Provider.Polly/PollyQoSProvider.cs | 6 +++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs index 99e7bf209..3821502a8 100644 --- a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs +++ b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs @@ -1,13 +1,18 @@ -using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; + +using Polly.CircuitBreaker; +using Polly.Timeout; + +using Microsoft.Extensions.DependencyInjection; using Ocelot.Configuration; using Ocelot.DependencyInjection; using Ocelot.Errors; using Ocelot.Logging; using Ocelot.Requester; - -using Polly.CircuitBreaker; -using Polly.Timeout; namespace Ocelot.Provider.Polly { diff --git a/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs b/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs index 0a0b3909e..e1605cb27 100644 --- a/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs +++ b/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs @@ -1,6 +1,12 @@ +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + using Ocelot.Logging; using Ocelot.Provider.Polly.Interfaces; +using Polly; using Polly.CircuitBreaker; namespace Ocelot.Provider.Polly diff --git a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs index 52a29568d..385b3255a 100644 --- a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs +++ b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs @@ -1,7 +1,11 @@ +using System; +using System.Net.Http; + using Ocelot.Configuration; using Ocelot.Logging; using Ocelot.Provider.Polly.Interfaces; - + +using Polly; using Polly.CircuitBreaker; using Polly.Timeout; From f759f4bc95f5e2304ccdd6f22d1b4d84c4d77ba8 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 2 Oct 2023 14:23:15 +0200 Subject: [PATCH 05/10] code review post merge --- .../OcelotBuilderExtensions.cs | 13 ++++--------- .../PollyCircuitBreakingDelegatingHandler.cs | 6 ------ src/Ocelot.Provider.Polly/PollyQoSProvider.cs | 6 +----- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs index 3821502a8..99e7bf209 100644 --- a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs +++ b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs @@ -1,18 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; - -using Polly.CircuitBreaker; -using Polly.Timeout; - -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Ocelot.Configuration; using Ocelot.DependencyInjection; using Ocelot.Errors; using Ocelot.Logging; using Ocelot.Requester; + +using Polly.CircuitBreaker; +using Polly.Timeout; namespace Ocelot.Provider.Polly { diff --git a/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs b/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs index e1605cb27..0a0b3909e 100644 --- a/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs +++ b/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs @@ -1,12 +1,6 @@ -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - using Ocelot.Logging; using Ocelot.Provider.Polly.Interfaces; -using Polly; using Polly.CircuitBreaker; namespace Ocelot.Provider.Polly diff --git a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs index 385b3255a..52a29568d 100644 --- a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs +++ b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs @@ -1,11 +1,7 @@ -using System; -using System.Net.Http; - using Ocelot.Configuration; using Ocelot.Logging; using Ocelot.Provider.Polly.Interfaces; - -using Polly; + using Polly.CircuitBreaker; using Polly.Timeout; From c37091e8a59bcc38e3ad5c65a3bcebfd928e7f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raynald=20Messi=C3=A9?= Date: Fri, 13 Oct 2023 09:06:00 +0200 Subject: [PATCH 06/10] Update src/Ocelot.Provider.Polly/PollyQoSProvider.cs Co-authored-by: Raman Maksimchuk --- src/Ocelot.Provider.Polly/PollyQoSProvider.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs index 52a29568d..a55c01f8d 100644 --- a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs +++ b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs @@ -1,9 +1,9 @@ -using Ocelot.Configuration; -using Ocelot.Logging; -using Ocelot.Provider.Polly.Interfaces; - -using Polly.CircuitBreaker; -using Polly.Timeout; +using Ocelot.Configuration; +using Ocelot.Logging; +using Ocelot.Provider.Polly.Interfaces; + +using Polly.CircuitBreaker; +using Polly.Timeout; namespace Ocelot.Provider.Polly { @@ -48,11 +48,14 @@ public PollyQoSProvider(DownstreamRoute route, IOcelotLoggerFactory loggerFactor } CircuitBreaker = new CircuitBreaker(circuitBreakerPolicy, timeoutPolicy); - } + } + + private const string ObsoleteConstructorMessage = $"Use the constructor {nameof(PollyQoSProvider)}({nameof(DownstreamRoute)} route, {nameof(IOcelotLoggerFactory)} loggerFactory)!"; - [Obsolete("Use the constructor PollyQoSProvider(DownstreamRoute route, IOcelotLoggerFactory loggerFactory)")] + [Obsolete(ObsoleteConstructorMessage)] public PollyQoSProvider(AsyncCircuitBreakerPolicy circuitBreakerPolicy, AsyncTimeoutPolicy timeoutPolicy, IOcelotLogger logger) { + throw new NotSupportedException(ObsoleteConstructorMessage); } public CircuitBreaker CircuitBreaker { get; } From b9d7f5b4ef8273394b57f28536330a6f06d05e86 Mon Sep 17 00:00:00 2001 From: raman-m Date: Fri, 13 Oct 2023 12:03:04 +0300 Subject: [PATCH 07/10] namespaces --- src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs | 2 -- .../PollyCircuitBreakingDelegatingHandler.cs | 1 - src/Ocelot.Provider.Polly/PollyQoSProvider.cs | 1 - 3 files changed, 4 deletions(-) diff --git a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs index 99e7bf209..0d167f571 100644 --- a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs +++ b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs @@ -1,11 +1,9 @@ using Microsoft.Extensions.DependencyInjection; - using Ocelot.Configuration; using Ocelot.DependencyInjection; using Ocelot.Errors; using Ocelot.Logging; using Ocelot.Requester; - using Polly.CircuitBreaker; using Polly.Timeout; diff --git a/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs b/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs index 0a0b3909e..94d66962f 100644 --- a/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs +++ b/src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs @@ -1,6 +1,5 @@ using Ocelot.Logging; using Ocelot.Provider.Polly.Interfaces; - using Polly.CircuitBreaker; namespace Ocelot.Provider.Polly diff --git a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs index a55c01f8d..bf91d5f16 100644 --- a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs +++ b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs @@ -1,7 +1,6 @@ using Ocelot.Configuration; using Ocelot.Logging; using Ocelot.Provider.Polly.Interfaces; - using Polly.CircuitBreaker; using Polly.Timeout; From 97b9373afdafcbc63d7935f3278969881c973460 Mon Sep 17 00:00:00 2001 From: raman-m Date: Fri, 13 Oct 2023 13:06:05 +0300 Subject: [PATCH 08/10] Refactor QoS provider --- src/Ocelot.Provider.Polly/PollyQoSProvider.cs | 44 ++++++++----------- .../Polly/PollyQoSProviderTests.cs | 10 ++++- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs index bf91d5f16..8a5145aa2 100644 --- a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs +++ b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs @@ -10,15 +10,11 @@ public class PollyQoSProvider : IPollyQoSProvider { public PollyQoSProvider(DownstreamRoute route, IOcelotLoggerFactory loggerFactory) { - AsyncCircuitBreakerPolicy circuitBreakerPolicy; - var logger = loggerFactory.CreateLogger(); - - _ = Enum.TryParse(route.QosOptions.TimeoutStrategy, out TimeoutStrategy strategy); - - var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(route.QosOptions.TimeoutValue), strategy); - + AsyncCircuitBreakerPolicy circuitBreakerPolicy = null; if (route.QosOptions.ExceptionsAllowedBeforeBreaking > 0) - { + { + var info = $"Route: '{GetRouteName(route)}; Breaker logging in {nameof(PollyQoSProvider)}: "; + var logger = loggerFactory.CreateLogger(); circuitBreakerPolicy = Policy .Handle() .Or() @@ -26,29 +22,20 @@ public PollyQoSProvider(DownstreamRoute route, IOcelotLoggerFactory loggerFactor .CircuitBreakerAsync( exceptionsAllowedBeforeBreaking: route.QosOptions.ExceptionsAllowedBeforeBreaking, durationOfBreak: TimeSpan.FromMilliseconds(route.QosOptions.DurationOfBreak), - onBreak: (ex, breakDelay) => - { - logger.LogError( - ".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex); - }, + onBreak: (ex, breakDelay) => + logger.LogError(info + $"Breaking the circuit for {breakDelay.TotalMilliseconds} ms!", ex), onReset: () => - { - logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."); - }, + logger.LogDebug(info + "Call OK! Closed the circuit again."), onHalfOpen: () => - { - logger.LogDebug(".Breaker logging: Half-open; next call is a trial."); - } + logger.LogDebug(info + "Half-open; Next call is a trial.") ); } - else - { - circuitBreakerPolicy = null; - } + _ = Enum.TryParse(route.QosOptions.TimeoutStrategy, out TimeoutStrategy strategy); + var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(route.QosOptions.TimeoutValue), strategy); CircuitBreaker = new CircuitBreaker(circuitBreakerPolicy, timeoutPolicy); - } - + } + private const string ObsoleteConstructorMessage = $"Use the constructor {nameof(PollyQoSProvider)}({nameof(DownstreamRoute)} route, {nameof(IOcelotLoggerFactory)} loggerFactory)!"; [Obsolete(ObsoleteConstructorMessage)] @@ -57,6 +44,11 @@ public PollyQoSProvider(AsyncCircuitBreakerPolicy circuitBreakerPolicy, AsyncTim throw new NotSupportedException(ObsoleteConstructorMessage); } - public CircuitBreaker CircuitBreaker { get; } + public CircuitBreaker CircuitBreaker { get; } + + private static string GetRouteName(DownstreamRoute route) + => string.IsNullOrWhiteSpace(route.ServiceName) + ? route.UpstreamPathTemplate?.Template ?? route.DownstreamPathTemplate?.Value ?? string.Empty + : route.ServiceName; } } diff --git a/test/Ocelot.UnitTests/Polly/PollyQoSProviderTests.cs b/test/Ocelot.UnitTests/Polly/PollyQoSProviderTests.cs index e04d56411..537712e01 100644 --- a/test/Ocelot.UnitTests/Polly/PollyQoSProviderTests.cs +++ b/test/Ocelot.UnitTests/Polly/PollyQoSProviderTests.cs @@ -1,7 +1,9 @@ using Ocelot.Configuration.Builder; using Ocelot.Logging; using Ocelot.Provider.Polly; - +using Polly.CircuitBreaker; +using Polly.Timeout; + namespace Ocelot.UnitTests.Polly { public class PollyQoSProviderTests @@ -18,7 +20,11 @@ public void Should_build() .Build(); var factory = new Mock(); var pollyQoSProvider = new PollyQoSProvider(route, factory.Object); - pollyQoSProvider.CircuitBreaker.ShouldNotBeNull(); + var policies = pollyQoSProvider.CircuitBreaker.ShouldNotBeNull() + .Policies.ShouldNotBeNull(); + policies.Length.ShouldBeGreaterThan(0); + policies.ShouldContain(p => p is AsyncCircuitBreakerPolicy); + policies.ShouldContain(p => p is AsyncTimeoutPolicy); } } } From 63bb3474422c1c819e1453c29cbc1a8b7fab1d63 Mon Sep 17 00:00:00 2001 From: raman-m Date: Fri, 13 Oct 2023 13:21:29 +0300 Subject: [PATCH 09/10] Refactor AddPolly extension --- .../OcelotBuilderExtensions.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs index 0d167f571..229b2171e 100644 --- a/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs +++ b/src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs @@ -20,15 +20,13 @@ public static IOcelotBuilder AddPolly(this IOcelotBuilder builder) {typeof(BrokenCircuitException), e => new RequestTimedOutError(e)}, }; - builder.Services.AddSingleton(errorMapping); - - static DelegatingHandler QosDelegatingHandlerDelegate(DownstreamRoute route, IOcelotLoggerFactory logger) - { - return new PollyCircuitBreakingDelegatingHandler(new PollyQoSProvider(route, logger), logger); - } - - builder.Services.AddSingleton((QosDelegatingHandlerDelegate)QosDelegatingHandlerDelegate); + builder.Services + .AddSingleton(errorMapping) + .AddSingleton(GetDelegatingHandler); return builder; - } + } + + private static DelegatingHandler GetDelegatingHandler(DownstreamRoute route, IOcelotLoggerFactory logger) + => new PollyCircuitBreakingDelegatingHandler(new PollyQoSProvider(route, logger), logger); } } From d26f34ee8136b62df4bcaa8c306f79f9ff843eb2 Mon Sep 17 00:00:00 2001 From: raman-m Date: Fri, 13 Oct 2023 19:32:39 +0300 Subject: [PATCH 10/10] Remove single quote because semicolon ends sentence --- src/Ocelot.Provider.Polly/PollyQoSProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs index 8a5145aa2..58a918162 100644 --- a/src/Ocelot.Provider.Polly/PollyQoSProvider.cs +++ b/src/Ocelot.Provider.Polly/PollyQoSProvider.cs @@ -13,7 +13,7 @@ public PollyQoSProvider(DownstreamRoute route, IOcelotLoggerFactory loggerFactor AsyncCircuitBreakerPolicy circuitBreakerPolicy = null; if (route.QosOptions.ExceptionsAllowedBeforeBreaking > 0) { - var info = $"Route: '{GetRouteName(route)}; Breaker logging in {nameof(PollyQoSProvider)}: "; + var info = $"Route: {GetRouteName(route)}; Breaker logging in {nameof(PollyQoSProvider)}: "; var logger = loggerFactory.CreateLogger(); circuitBreakerPolicy = Policy .Handle()