|
1 | 1 | using System; |
2 | | -using System.Diagnostics.CodeAnalysis; |
3 | 2 | using System.Net; |
4 | 3 | using System.Net.Http; |
5 | 4 | using Duende.IdentityModel.Client; |
6 | 5 | using Microsoft.AspNetCore.Hosting; |
7 | 6 | using Microsoft.Extensions.Configuration; |
8 | 7 | using Microsoft.Extensions.Hosting; |
9 | 8 | using Polly; |
| 9 | +using Polly.CircuitBreaker; |
| 10 | +using Polly.Retry; |
| 11 | +using Polly.Timeout; |
10 | 12 | using Serval.Client; |
11 | 13 | using SIL.XForge.Configuration; |
12 | 14 | using SIL.XForge.Scripture.Models; |
13 | 15 | using SIL.XForge.Scripture.Services; |
14 | 16 |
|
15 | 17 | namespace Microsoft.Extensions.DependencyInjection; |
16 | 18 |
|
17 | | -[ExcludeFromCodeCoverage(Justification = "This logic will only work in a valid ASP.NET Core Context")] |
18 | 19 | public static class MachineServiceCollectionExtensions |
19 | 20 | { |
20 | 21 | public static IServiceCollection AddSFMachine( |
@@ -59,7 +60,8 @@ IWebHostEnvironment env |
59 | 60 | .AddHttpClient(MachineApi.HttpClientName) |
60 | 61 | .SetHandlerLifetime(TimeSpan.FromMinutes(5)) |
61 | 62 | .AddPolicyHandler(GetRetryPolicy()) |
62 | | - .AddPolicyHandler(GetCircuitBreakerPolicy()); |
| 63 | + .AddPolicyHandler(GetCircuitBreakerPolicy()) |
| 64 | + .AddPolicyHandler(GetTimeoutPolicy()); |
63 | 65 | services.AddSingleton<ITranslationEnginesClient, TranslationEnginesClient>(sp => |
64 | 66 | { |
65 | 67 | // Instantiate the translation engines client with our named HTTP client |
@@ -95,15 +97,20 @@ IWebHostEnvironment env |
95 | 97 | return services; |
96 | 98 | } |
97 | 99 |
|
98 | | - private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy() => |
| 100 | + private static AsyncRetryPolicy<HttpResponseMessage> GetRetryPolicy() => |
99 | 101 | Policy<HttpResponseMessage> |
100 | 102 | .Handle<HttpRequestException>() |
101 | 103 | .OrResult(r => r.StatusCode >= HttpStatusCode.InternalServerError) |
102 | 104 | .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); |
103 | 105 |
|
104 | | - private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy() => |
| 106 | + private static AsyncCircuitBreakerPolicy<HttpResponseMessage> GetCircuitBreakerPolicy() => |
105 | 107 | Policy<HttpResponseMessage> |
106 | 108 | .Handle<HttpRequestException>() |
107 | 109 | .OrResult(r => r.StatusCode >= HttpStatusCode.InternalServerError) |
108 | 110 | .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); |
| 111 | + |
| 112 | + private static AsyncTimeoutPolicy<HttpResponseMessage> GetTimeoutPolicy() => |
| 113 | + // NOTE: The Serval Get Build endpoint has a long polling timeout of 40 seconds, |
| 114 | + // so ensure any timeout values support this |
| 115 | + Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromMinutes(5), TimeoutStrategy.Pessimistic); |
109 | 116 | } |
0 commit comments