| File: HttpClientFactory.cs | Web Access |
| Project: src\bench\Libraries\Microsoft.Extensions.Http.Resilience.PerformanceTests\Microsoft.Extensions.Http.Resilience.PerformanceTests.csproj (Microsoft.Extensions.Http.Resilience.PerformanceTests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using Microsoft.Extensions.Compliance.Redaction; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.Extensions.Http.Resilience.PerformanceTests; [Flags] [SuppressMessage("Performance", "EA0004:Make types declared in an executable internal", Justification = "Needs to be public for BenchmarkDotNet consumption")] public enum HedgingClientType { Weighted = 1 << 0, Ordered = 1 << 1, ManyRoutes = 1 << 2, NoRoutes = 1 << 3, } internal static class HttpClientFactory { internal const string EmptyClient = "Empty"; internal const string StandardClient = "Standard"; internal const string SingleHandlerClient = "SingleHandler"; internal const string PrimaryEndpoint = "http://localhost1"; internal const string SecondaryEndpoint = "http://localhost2"; public static ServiceProvider InitializeServiceProvider(params HedgingClientType[] clientType) { var services = new ServiceCollection(); services .AddMetrics() .AddSingleton<IRedactorProvider>(NullRedactorProvider.Instance) .AddTransient<NoRemoteCallHandler>() .AddHttpClient(StandardClient, client => client.Timeout = Timeout.InfiniteTimeSpan) .AddStandardResilienceHandler() .Services .AddHttpClient(StandardClient) .ConfigurePrimaryHttpMessageHandler(() => new NoRemoteCallHandler()) .Services .AddHttpClient(EmptyClient, client => client.Timeout = Timeout.InfiniteTimeSpan) .ConfigurePrimaryHttpMessageHandler(() => new NoRemoteCallHandler()) .Services .AddHttpClient(SingleHandlerClient, client => client.Timeout = Timeout.InfiniteTimeSpan) .AddHttpMessageHandler(() => new EmptyHandler()) .ConfigurePrimaryHttpMessageHandler(() => new NoRemoteCallHandler()); services.RemoveAll<ILoggerFactory>(); services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance); foreach (var type in clientType) { services.AddHedging(type); } return services.BuildServiceProvider(); } private static void AddHedging(this IServiceCollection services, HedgingClientType clientType) { var clientBuilder = services.AddHttpClient(clientType.ToString(), client => client.Timeout = Timeout.InfiniteTimeSpan); var hedgingBuilder = clientBuilder.AddStandardHedgingHandler().SelectPipelineByAuthority(); _ = clientBuilder.AddHttpMessageHandler<NoRemoteCallHandler>(); if (clientType.HasFlag(HedgingClientType.NoRoutes)) { return; } int routes = clientType.HasFlag(HedgingClientType.ManyRoutes) ? 50 : 2; if (clientType.HasFlag(HedgingClientType.Ordered)) { hedgingBuilder.RoutingStrategyBuilder.ConfigureOrderedGroups(options => { options.Groups = Enumerable.Repeat(0, routes).Select(_ => { return new UriEndpointGroup { Endpoints = new[] { new WeightedUriEndpoint { Uri = new Uri(PrimaryEndpoint) }, new WeightedUriEndpoint { Uri = new Uri(SecondaryEndpoint) } } }; }).ToArray(); }); } else { hedgingBuilder.RoutingStrategyBuilder.ConfigureWeightedGroups(options => { options.Groups = Enumerable.Repeat(0, routes).Select(_ => { return new WeightedUriEndpointGroup { Endpoints = new[] { new WeightedUriEndpoint { Uri = new Uri(PrimaryEndpoint) }, new WeightedUriEndpoint { Uri = new Uri(SecondaryEndpoint) } } }; }).ToArray(); }); } } }