refactor(backend): use single shared HTTP client with backoff
This commit is contained in:
		
							parent
							
								
									bba322bd22
								
							
						
					
					
						commit
						5d452824cd
					
				
					 9 changed files with 232 additions and 75 deletions
				
			
		|  | @ -21,8 +21,10 @@ using Foxnouns.Backend.Services; | |||
| using Foxnouns.Backend.Services.Auth; | ||||
| using Foxnouns.Backend.Services.V1; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using Microsoft.Extensions.Http.Resilience; | ||||
| using Minio; | ||||
| using NodaTime; | ||||
| using Polly; | ||||
| using Prometheus; | ||||
| using Serilog; | ||||
| using Serilog.Events; | ||||
|  | @ -100,6 +102,40 @@ public static class WebApplicationExtensions | |||
|         builder.Host.ConfigureServices( | ||||
|             (ctx, services) => | ||||
|             { | ||||
|                 // create a single HTTP client for all requests. | ||||
|                 // it's also configured with a retry mechanism, so that requests aren't immediately lost to the void if they fail | ||||
|                 services.AddSingleton<HttpClient>(_ => | ||||
|                 { | ||||
|                     // ReSharper disable once SuggestVarOrType_Elsewhere | ||||
|                     var retryPipeline = new ResiliencePipelineBuilder<HttpResponseMessage>() | ||||
|                         .AddRetry( | ||||
|                             new HttpRetryStrategyOptions | ||||
|                             { | ||||
|                                 BackoffType = DelayBackoffType.Linear, | ||||
|                                 MaxRetryAttempts = 3, | ||||
|                             } | ||||
|                         ) | ||||
|                         .Build(); | ||||
| 
 | ||||
|                     var resilienceHandler = new ResilienceHandler(retryPipeline) | ||||
|                     { | ||||
|                         InnerHandler = new SocketsHttpHandler | ||||
|                         { | ||||
|                             PooledConnectionLifetime = TimeSpan.FromMinutes(15), | ||||
|                         }, | ||||
|                     }; | ||||
| 
 | ||||
|                     var client = new HttpClient(resilienceHandler); | ||||
|                     client.DefaultRequestHeaders.Remove("User-Agent"); | ||||
|                     client.DefaultRequestHeaders.Remove("Accept"); | ||||
|                     client.DefaultRequestHeaders.Add( | ||||
|                         "User-Agent", | ||||
|                         $"pronouns.cc/{BuildInfo.Version}" | ||||
|                     ); | ||||
|                     client.DefaultRequestHeaders.Add("Accept", "application/json"); | ||||
|                     return client; | ||||
|                 }); | ||||
| 
 | ||||
|                 services | ||||
|                     .AddQueue() | ||||
|                     .AddSmtpMailer(ctx.Configuration) | ||||
|  |  | |||
|  | @ -25,12 +25,13 @@ | |||
|             <PrivateAssets>all</PrivateAssets> | ||||
|         </PackageReference> | ||||
|         <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.2"/> | ||||
|         <PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.2.0"/> | ||||
|         <PackageReference Include="MimeKit" Version="4.10.0"/> | ||||
|         <PackageReference Include="Minio" Version="6.0.4"/> | ||||
|         <PackageReference Include="Newtonsoft.Json" Version="13.0.3"/> | ||||
|         <PackageReference Include="NodaTime" Version="3.2.1"/> | ||||
|         <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" /> | ||||
|         <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="9.0.4" /> | ||||
|         <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4"/> | ||||
|         <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="9.0.4"/> | ||||
|         <PackageReference Include="Npgsql.Json.NET" Version="9.0.3"/> | ||||
|         <PackageReference Include="prometheus-net" Version="8.2.1"/> | ||||
|         <PackageReference Include="prometheus-net.AspNetCore" Version="8.2.1"/> | ||||
|  | @ -38,14 +39,14 @@ | |||
|             <PrivateAssets>all</PrivateAssets> | ||||
|             <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||
|         </PackageReference> | ||||
|         <PackageReference Include="Scalar.AspNetCore" Version="2.0.26" /> | ||||
|         <PackageReference Include="Sentry.AspNetCore" Version="5.3.0" /> | ||||
|         <PackageReference Include="Scalar.AspNetCore" Version="2.0.26"/> | ||||
|         <PackageReference Include="Sentry.AspNetCore" Version="5.3.0"/> | ||||
|         <PackageReference Include="Serilog" Version="4.2.0"/> | ||||
|         <PackageReference Include="Serilog.AspNetCore" Version="9.0.0"/> | ||||
|         <PackageReference Include="Serilog.Sinks.Console" Version="6.0.0"/> | ||||
|         <PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0"/> | ||||
|         <PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" /> | ||||
|         <PackageReference Include="StackExchange.Redis" Version="2.8.31" /> | ||||
|         <PackageReference Include="SixLabors.ImageSharp" Version="3.1.7"/> | ||||
|         <PackageReference Include="StackExchange.Redis" Version="2.8.31"/> | ||||
|         <PackageReference Include="System.Text.Json" Version="9.0.2"/> | ||||
|         <PackageReference Include="System.Text.RegularExpressions" Version="4.3.1"/> | ||||
|         <PackageReference Include="Yort.Xid.Net" Version="2.0.1"/> | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ using NodaTime.Text; | |||
| namespace Foxnouns.Backend.Jobs; | ||||
| 
 | ||||
| public class CreateDataExportJob( | ||||
|     HttpClient client, | ||||
|     DatabaseContext db, | ||||
|     IClock clock, | ||||
|     UserRendererService userRenderer, | ||||
|  | @ -36,7 +37,6 @@ public class CreateDataExportJob( | |||
|     ILogger logger | ||||
| ) | ||||
| { | ||||
|     private static readonly HttpClient Client = new(); | ||||
|     private readonly ILogger _logger = logger.ForContext<CreateDataExportJob>(); | ||||
| 
 | ||||
|     public static void Enqueue(Snowflake userId) | ||||
|  | @ -201,7 +201,7 @@ public class CreateDataExportJob( | |||
|         if (s3Path == null) | ||||
|             return; | ||||
| 
 | ||||
|         HttpResponseMessage resp = await Client.GetAsync(s3Path); | ||||
|         HttpResponseMessage resp = await client.GetAsync(s3Path); | ||||
|         if (resp.StatusCode != HttpStatusCode.OK) | ||||
|         { | ||||
|             _logger.Warning("S3 path {S3Path} returned a non-200 status, not saving file", s3Path); | ||||
|  |  | |||
|  | @ -34,6 +34,7 @@ public partial class FediverseAuthService | |||
|         ILogger logger, | ||||
|         Config config, | ||||
|         DatabaseContext db, | ||||
|         HttpClient client, | ||||
|         KeyCacheService keyCacheService, | ||||
|         ISnowflakeGenerator snowflakeGenerator | ||||
|     ) | ||||
|  | @ -43,12 +44,7 @@ public partial class FediverseAuthService | |||
|         _db = db; | ||||
|         _keyCacheService = keyCacheService; | ||||
|         _snowflakeGenerator = snowflakeGenerator; | ||||
| 
 | ||||
|         _client = new HttpClient(); | ||||
|         _client.DefaultRequestHeaders.Remove("User-Agent"); | ||||
|         _client.DefaultRequestHeaders.Remove("Accept"); | ||||
|         _client.DefaultRequestHeaders.Add("User-Agent", $"pronouns.cc/{BuildInfo.Version}"); | ||||
|         _client.DefaultRequestHeaders.Add("Accept", "application/json"); | ||||
|         _client = client; | ||||
|     } | ||||
| 
 | ||||
|     public async Task<string> GenerateAuthUrlAsync( | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ public partial class RemoteAuthService | |||
|     ) | ||||
|     { | ||||
|         var redirectUri = $"{config.BaseUrl}/auth/callback/discord"; | ||||
|         HttpResponseMessage resp = await _httpClient.PostAsync( | ||||
|         HttpResponseMessage resp = await client.PostAsync( | ||||
|             _discordTokenUri, | ||||
|             new FormUrlEncodedContent( | ||||
|                 new Dictionary<string, string> | ||||
|  | @ -59,7 +59,7 @@ public partial class RemoteAuthService | |||
|         var req = new HttpRequestMessage(HttpMethod.Get, _discordUserUri); | ||||
|         req.Headers.Add("Authorization", $"{token.TokenType} {token.AccessToken}"); | ||||
| 
 | ||||
|         HttpResponseMessage resp2 = await _httpClient.SendAsync(req, ct); | ||||
|         HttpResponseMessage resp2 = await client.SendAsync(req, ct); | ||||
|         resp2.EnsureSuccessStatusCode(); | ||||
|         DiscordUserResponse? user = await resp2.Content.ReadFromJsonAsync<DiscordUserResponse>(ct); | ||||
|         if (user == null) | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ public partial class RemoteAuthService | |||
|     ) | ||||
|     { | ||||
|         var redirectUri = $"{config.BaseUrl}/auth/callback/google"; | ||||
|         HttpResponseMessage resp = await _httpClient.PostAsync( | ||||
|         HttpResponseMessage resp = await client.PostAsync( | ||||
|             _googleTokenUri, | ||||
|             new FormUrlEncodedContent( | ||||
|                 new Dictionary<string, string> | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ public partial class RemoteAuthService | |||
|     ) | ||||
|     { | ||||
|         var redirectUri = $"{config.BaseUrl}/auth/callback/tumblr"; | ||||
|         HttpResponseMessage resp = await _httpClient.PostAsync( | ||||
|         HttpResponseMessage resp = await client.PostAsync( | ||||
|             _tumblrTokenUri, | ||||
|             new FormUrlEncodedContent( | ||||
|                 new Dictionary<string, string> | ||||
|  | @ -62,7 +62,7 @@ public partial class RemoteAuthService | |||
|         var req = new HttpRequestMessage(HttpMethod.Get, _tumblrUserUri); | ||||
|         req.Headers.Add("Authorization", $"Bearer {token.AccessToken}"); | ||||
| 
 | ||||
|         HttpResponseMessage resp2 = await _httpClient.SendAsync(req, ct); | ||||
|         HttpResponseMessage resp2 = await client.SendAsync(req, ct); | ||||
|         if (!resp2.IsSuccessStatusCode) | ||||
|         { | ||||
|             string respBody = await resp2.Content.ReadAsStringAsync(ct); | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ using Microsoft.EntityFrameworkCore; | |||
| namespace Foxnouns.Backend.Services.Auth; | ||||
| 
 | ||||
| public partial class RemoteAuthService( | ||||
|     HttpClient client, | ||||
|     Config config, | ||||
|     ILogger logger, | ||||
|     DatabaseContext db, | ||||
|  | @ -32,7 +33,6 @@ public partial class RemoteAuthService( | |||
| ) | ||||
| { | ||||
|     private readonly ILogger _logger = logger.ForContext<RemoteAuthService>(); | ||||
|     private readonly HttpClient _httpClient = new(); | ||||
| 
 | ||||
|     public record RemoteUser(string Id, string Username); | ||||
| 
 | ||||
|  |  | |||
|  | @ -155,6 +155,18 @@ | |||
|           "Microsoft.Extensions.Primitives": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Http.Resilience": { | ||||
|         "type": "Direct", | ||||
|         "requested": "[9.2.0, )", | ||||
|         "resolved": "9.2.0", | ||||
|         "contentHash": "Km+YyCuk1IaeOsAzPDygtgsUOh3Fi89hpA18si0tFJmpSBf9aKzP9ffV5j7YOoVDvRWirpumXAPQzk1inBsvKw==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Configuration.Binder": "9.0.2", | ||||
|           "Microsoft.Extensions.Http.Diagnostics": "9.2.0", | ||||
|           "Microsoft.Extensions.ObjectPool": "9.0.2", | ||||
|           "Microsoft.Extensions.Resilience": "9.2.0" | ||||
|         } | ||||
|       }, | ||||
|       "MimeKit": { | ||||
|         "type": "Direct", | ||||
|         "requested": "[4.10.0, )", | ||||
|  | @ -537,6 +549,16 @@ | |||
|           "Microsoft.Extensions.Logging": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.AmbientMetadata.Application": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.2.0", | ||||
|         "contentHash": "GMCX3zybUB22aAADjYPXrWhhd1HNMkcY5EcFAJnXy/4k5pPpJ6TS4VRl37xfrtosNyzbpO2SI7pd2Q5PvggSdg==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Configuration": "9.0.2", | ||||
|           "Microsoft.Extensions.Hosting.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Caching.Abstractions": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.2", | ||||
|  | @ -545,13 +567,22 @@ | |||
|           "Microsoft.Extensions.Primitives": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Compliance.Abstractions": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.2.0", | ||||
|         "contentHash": "Te+N4xphDlGIS90lKJMZyezFiMWKLAtYV2/M8gGJG4thH6xyC7LWhMzgz2+tWMehxwZlBUq2D9DvVpjKBZFTPQ==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.ObjectPool": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Configuration": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.0", | ||||
|         "contentHash": "YIMO9T3JL8MeEXgVozKt2v79hquo/EFtnY0vgxmLnUvk1Rei/halI7kOWZL2RBeV9FMGzgM9LZA8CVaNwFMaNA==", | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "EBZW+u96tApIvNtjymXEIS44tH0I/jNwABHo4c33AchWOiDWCq2rL3klpnIo+xGrxoVGJzPDISV6hZ+a9C9SzQ==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Primitives": "9.0.0" | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Primitives": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Configuration.Abstractions": { | ||||
|  | @ -564,10 +595,10 @@ | |||
|       }, | ||||
|       "Microsoft.Extensions.Configuration.Binder": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.0", | ||||
|         "contentHash": "RiScL99DcyngY9zJA2ROrri7Br8tn5N4hP4YNvGdTN/bvg1A3dwvDOxHnNZ3Im7x2SJ5i4LkX1uPiR/MfSFBLQ==", | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "krJ04xR0aPXrOf5dkNASg6aJjsdzexvsMRL6UNOUjiTzqBvRr95sJ1owoKEm89bSONQCfZNhHrAFV9ahDqIPIw==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.0" | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.DependencyInjection": { | ||||
|  | @ -583,6 +614,14 @@ | |||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "MNe7GSTBf3jQx5vYrXF0NZvn6l7hUKF6J54ENfAgCO8y6xjN1XUmKKWG464LP2ye6QqDiA1dkaWEZBYnhoZzjg==" | ||||
|       }, | ||||
|       "Microsoft.Extensions.DependencyInjection.AutoActivation": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.2.0", | ||||
|         "contentHash": "WcwfTpl3IcPcaahTVEaJwMUg1eWog1SkIA6jQZZFqMXiMX9/tVkhNB6yzUQmBdGWdlWDDRKpOmK7T7x1Uu05pQ==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Hosting.Abstractions": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.DependencyModel": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.2", | ||||
|  | @ -590,54 +629,74 @@ | |||
|       }, | ||||
|       "Microsoft.Extensions.Diagnostics": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.0", | ||||
|         "contentHash": "0CF9ZrNw5RAlRfbZuVIvzzhP8QeWqHiUmMBU/2H7Nmit8/vwP3/SbHeEctth7D4Gz2fBnEbokPc1NU8/j/1ZLw==", | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "kwFWk6DPaj1Roc0CExRv+TTwjsiERZA730jQIPlwCcS5tMaCAQtaGfwAK0z8CMFpVTiT+MgKXpd/P50qVCuIgg==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Configuration": "9.0.0", | ||||
|           "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.0" | ||||
|           "Microsoft.Extensions.Configuration": "9.0.2", | ||||
|           "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Diagnostics.Abstractions": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.0", | ||||
|         "contentHash": "1K8P7XzuzX8W8pmXcZjcrqS6x5eSSdvhQohmcpgiQNY/HlDAlnrhR9dvlURfFz428A+RTCJpUyB+aKTA6AgVcQ==", | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "kFwIZEC/37cwKuEm/nXvjF7A/Myz9O7c7P9Csgz6AOiiDE62zdOG5Bu7VkROu1oMYaX0wgijPJ5LqVt6+JKjVg==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Options": "9.0.0" | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Options": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Diagnostics.ExceptionSummarization": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.2.0", | ||||
|         "contentHash": "et5JevHsLv1w1O1Zhb6LiUfai/nmDRzIHnbrZJdzLsIbbMCKTZpeHuANYIppAD//n12KvgOne05j4cu0GhG9gw==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.FileProviders.Abstractions": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.0", | ||||
|         "contentHash": "uK439QzYR0q2emLVtYzwyK3x+T5bTY4yWsd/k/ZUS9LR6Sflp8MIdhGXW8kQCd86dQD4tLqvcbLkku8qHY263Q==", | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "IcOBmTlr2jySswU+3x8c3ql87FRwTVPQgVKaV5AXzPT5u0VItfNU8SMbESpdSp5STwxT/1R99WYszgHWsVkzhg==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Primitives": "9.0.0" | ||||
|           "Microsoft.Extensions.Primitives": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Hosting.Abstractions": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.0", | ||||
|         "contentHash": "yUKJgu81ExjvqbNWqZKshBbLntZMbMVz/P7Way2SBx7bMqA08Mfdc9O7hWDKAiSp+zPUGT6LKcSCQIPeDK+CCw==", | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "PvjZW6CMdZbPbOwKsQXYN5VPtIWZQqdTRuBPZiW3skhU3hymB17XSlLVC4uaBbDZU+/3eHG3p80y+MzZxZqR7Q==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.FileProviders.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Logging.Abstractions": "9.0.0" | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.FileProviders.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Logging.Abstractions": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Http": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.0", | ||||
|         "contentHash": "DqI4q54U4hH7bIAq9M5a/hl5Odr/KBAoaZ0dcT4OgutD8dook34CbkvAfAIzkMVjYXiL+E5ul9etwwqiX4PHGw==", | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "34+kcwxPZr3Owk9eZx268+gqGNB8G/8Y96gZHomxam0IOH08FhPBjPrLWDtKdVn4+sVUUJnJMpECSTJi4XXCcg==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Diagnostics": "9.0.0", | ||||
|           "Microsoft.Extensions.Logging": "9.0.0", | ||||
|           "Microsoft.Extensions.Logging.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Options": "9.0.0" | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Diagnostics": "9.0.2", | ||||
|           "Microsoft.Extensions.Logging": "9.0.2", | ||||
|           "Microsoft.Extensions.Logging.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Options": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Http.Diagnostics": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.2.0", | ||||
|         "contentHash": "Eeup1LuD5hVk5SsKAuX1D7I9sF380MjrNG10IaaauRLOmrRg8rq2TA8PYTXVBXf3MLkZ6m2xpBqRbZdxf8ygkg==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.DependencyInjection.AutoActivation": "9.2.0", | ||||
|           "Microsoft.Extensions.Http": "9.0.2", | ||||
|           "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.2", | ||||
|           "Microsoft.Extensions.Telemetry": "9.2.0", | ||||
|           "System.IO.Pipelines": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Logging": { | ||||
|  | @ -660,23 +719,23 @@ | |||
|       }, | ||||
|       "Microsoft.Extensions.Logging.Configuration": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.0", | ||||
|         "contentHash": "H05HiqaNmg6GjH34ocYE9Wm1twm3Oz2aXZko8GTwGBzM7op2brpAA8pJ5yyD1OpS1mXUtModBYOlcZ/wXeWsSg==", | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "pnwYZE7U6d3Y6iMVqADOAUUMMBGYAQPsT3fMwVr/V1Wdpe5DuVGFcViZavUthSJ5724NmelIl1cYy+kRfKfRPQ==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Configuration": "9.0.0", | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Configuration.Binder": "9.0.0", | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Logging": "9.0.0", | ||||
|           "Microsoft.Extensions.Logging.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Options": "9.0.0", | ||||
|           "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.0" | ||||
|           "Microsoft.Extensions.Configuration": "9.0.2", | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Configuration.Binder": "9.0.2", | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Logging": "9.0.2", | ||||
|           "Microsoft.Extensions.Logging.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Options": "9.0.2", | ||||
|           "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.ObjectPool": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "7.0.0", | ||||
|         "contentHash": "udvKco0sAVgYGTBnHUb0tY9JQzJ/nPDiv/8PIyz69wl1AibeCDZOLVVI+6156dPfHmJH7ws5oUJRiW4ZmAvuuA==" | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "nWx7uY6lfkmtpyC2dGc0IxtrZZs/LnLCQHw3YYQucbqWj8a27U/dZ+eh72O3ZiolqLzzLkVzoC+w/M8dZwxRTw==" | ||||
|       }, | ||||
|       "Microsoft.Extensions.Options": { | ||||
|         "type": "Transitive", | ||||
|  | @ -689,14 +748,14 @@ | |||
|       }, | ||||
|       "Microsoft.Extensions.Options.ConfigurationExtensions": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.0.0", | ||||
|         "contentHash": "Ob3FXsXkcSMQmGZi7qP07EQ39kZpSBlTcAZLbJLdI4FIf0Jug8biv2HTavWmnTirchctPlq9bl/26CXtQRguzA==", | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "OPm1NXdMg4Kb4Kz+YHdbBQfekh7MqQZ7liZ5dYUd+IbJakinv9Fl7Ck6Strbgs0a6E76UGbP/jHR532K/7/feQ==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Configuration.Binder": "9.0.0", | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0", | ||||
|           "Microsoft.Extensions.Options": "9.0.0", | ||||
|           "Microsoft.Extensions.Primitives": "9.0.0" | ||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Configuration.Binder": "9.0.2", | ||||
|           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.Options": "9.0.2", | ||||
|           "Microsoft.Extensions.Primitives": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Primitives": { | ||||
|  | @ -704,6 +763,42 @@ | |||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "puBMtKe/wLuYa7H6docBkLlfec+h8L35DXqsDKKJgW0WY5oCwJ3cBJKcDaZchv6knAyqOMfsl6VUbaR++E5LXA==" | ||||
|       }, | ||||
|       "Microsoft.Extensions.Resilience": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.2.0", | ||||
|         "contentHash": "dyaM+Jeznh/i21bOrrRs3xceFfn0571EOjOq95dRXmL1rHDLC4ExhACJ2xipRBP6g1AgRNqmryi+hMrVWWgmlg==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Diagnostics": "9.0.2", | ||||
|           "Microsoft.Extensions.Diagnostics.ExceptionSummarization": "9.2.0", | ||||
|           "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.2", | ||||
|           "Microsoft.Extensions.Telemetry.Abstractions": "9.2.0", | ||||
|           "Polly.Extensions": "8.4.2", | ||||
|           "Polly.RateLimiting": "8.4.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Telemetry": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.2.0", | ||||
|         "contentHash": "4+bw7W4RrAMrND9TxonnSmzJOdXiPxljoda8OPJiReIN607mKCc0t0Mf28sHNsTujO1XQw28wsI0poxeeQxohw==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.AmbientMetadata.Application": "9.2.0", | ||||
|           "Microsoft.Extensions.DependencyInjection.AutoActivation": "9.2.0", | ||||
|           "Microsoft.Extensions.Logging.Configuration": "9.0.2", | ||||
|           "Microsoft.Extensions.ObjectPool": "9.0.2", | ||||
|           "Microsoft.Extensions.Telemetry.Abstractions": "9.2.0" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.Extensions.Telemetry.Abstractions": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "9.2.0", | ||||
|         "contentHash": "kEl+5G3RqS20XaEhHh/nOugcjKEK+rgVtMJra1iuwNzdzQXElelf3vu8TugcT7rIZ/T4T76EKW1OX/fmlxz4hw==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Compliance.Abstractions": "9.2.0", | ||||
|           "Microsoft.Extensions.Logging.Abstractions": "9.0.2", | ||||
|           "Microsoft.Extensions.ObjectPool": "9.0.2", | ||||
|           "Microsoft.Extensions.Options": "9.0.2" | ||||
|         } | ||||
|       }, | ||||
|       "Microsoft.NETCore.Platforms": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "1.1.1", | ||||
|  | @ -760,6 +855,30 @@ | |||
|           "System.IO.Pipelines": "5.0.1" | ||||
|         } | ||||
|       }, | ||||
|       "Polly.Core": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "8.4.2", | ||||
|         "contentHash": "BpE2I6HBYYA5tF0Vn4eoQOGYTYIK1BlF5EXVgkWGn3mqUUjbXAr13J6fZVbp7Q3epRR8yshacBMlsHMhpOiV3g==" | ||||
|       }, | ||||
|       "Polly.Extensions": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "8.4.2", | ||||
|         "contentHash": "GZ9vRVmR0jV2JtZavt+pGUsQ1O1cuRKG7R7VOZI6ZDy9y6RNPvRvXK1tuS4ffUrv8L0FTea59oEuQzgS0R7zSA==", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.Logging.Abstractions": "8.0.0", | ||||
|           "Microsoft.Extensions.Options": "8.0.0", | ||||
|           "Polly.Core": "8.4.2" | ||||
|         } | ||||
|       }, | ||||
|       "Polly.RateLimiting": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "8.4.2", | ||||
|         "contentHash": "ehTImQ/eUyO07VYW2WvwSmU9rRH200SKJ/3jku9rOkyWE0A2JxNFmAVms8dSn49QLSjmjFRRSgfNyOgr/2PSmA==", | ||||
|         "dependencies": { | ||||
|           "Polly.Core": "8.4.2", | ||||
|           "System.Threading.RateLimiting": "8.0.0" | ||||
|         } | ||||
|       }, | ||||
|       "Sentry": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "5.3.0", | ||||
|  | @ -901,8 +1020,8 @@ | |||
|       }, | ||||
|       "System.IO.Pipelines": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "7.0.0", | ||||
|         "contentHash": "jRn6JYnNPW6xgQazROBLSfpdoczRw694vO5kKvMcNnpXuolEixUyw6IBuBs2Y2mlSX/LdLvyyWmfXhaI3ND1Yg==" | ||||
|         "resolved": "9.0.2", | ||||
|         "contentHash": "UIBaK7c/A3FyQxmX/747xw4rCUkm1BhNiVU617U5jweNJssNjLJkPUGhBsrlDG0BpKWCYKsncD+Kqpy4KmvZZQ==" | ||||
|       }, | ||||
|       "System.Reactive": { | ||||
|         "type": "Transitive", | ||||
|  | @ -940,6 +1059,11 @@ | |||
|         "type": "Transitive", | ||||
|         "resolved": "7.0.0", | ||||
|         "contentHash": "qmeeYNROMsONF6ndEZcIQ+VxR4Q/TX/7uIVLJqtwIWL7dDWeh0l1UIqgo4wYyjG//5lUNhwkLDSFl+pAWO6oiA==" | ||||
|       }, | ||||
|       "System.Threading.RateLimiting": { | ||||
|         "type": "Transitive", | ||||
|         "resolved": "8.0.0", | ||||
|         "contentHash": "7mu9v0QDv66ar3DpGSZHg9NuNcxDaaAcnMULuZlaTpP9+hwXhrxNGsF5GmLkSHxFdb5bBc1TzeujsRgTrPWi+Q==" | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue