-
Notifications
You must be signed in to change notification settings - Fork 862
Expand file tree
/
Copy pathHttpClientFactory.cs
More file actions
118 lines (104 loc) · 4.42 KB
/
HttpClientFactory.cs
File metadata and controls
118 lines (104 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// 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.Compliance.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Telemetry.Metering;
#pragma warning disable R9A033 // Replace uses of 'Enum.GetName' and 'Enum.ToString' with the '[EnumStrings]' code generator for improved performance
namespace Microsoft.Extensions.Http.Resilience.Bench;
[Flags]
[SuppressMessage("Performance", "R9A031: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,
}
internal static class HttpClientFactory
{
internal const string EmptyClient = "Empty";
internal const string StandardClient = "Standard";
private const string HedgingEndpoint1 = "http://localhost1";
private const string HedgingEndpoint2 = "http://localhost2";
public static ServiceProvider InitializeServiceProvider(HedgingClientType clientType)
{
var services = new ServiceCollection();
services
.RegisterMetering()
.AddSingleton<IRedactorProvider>(NullRedactorProvider.Instance)
.AddTransient<NoRemoteCallHandler>()
.AddHedging(clientType)
.AddHttpClient(StandardClient, client => client.Timeout = Timeout.InfiniteTimeSpan)
.AddStandardResilienceHandler()
.Services
.AddHttpClient(StandardClient)
.AddHttpMessageHandler<NoRemoteCallHandler>()
.Services
.AddHttpClient(EmptyClient, client => client.Timeout = Timeout.InfiniteTimeSpan)
.AddHttpMessageHandler<NoRemoteCallHandler>();
services.RemoveAll<ILoggerFactory>();
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
return services.BuildServiceProvider();
}
private static IServiceCollection AddHedging(this IServiceCollection services, HedgingClientType clientType)
{
var clientBuilder = services.AddHttpClient(clientType.ToString(), client => client.Timeout = Timeout.InfiniteTimeSpan);
var hedgingBuilder = clientBuilder.AddStandardHedgingHandler().SelectStrategyByAuthority(SimpleClassifications.PublicData);
_ = clientBuilder.AddHttpMessageHandler<NoRemoteCallHandler>();
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 EndpointGroup
{
Endpoints = new[]
{
new WeightedEndpoint
{
Uri = new Uri(HedgingEndpoint1)
},
new WeightedEndpoint
{
Uri = new Uri(HedgingEndpoint2)
}
}
};
}).ToArray();
});
}
else
{
hedgingBuilder.RoutingStrategyBuilder.ConfigureWeightedGroups(options =>
{
options.Groups = Enumerable.Repeat(0, routes).Select(_ =>
{
return new WeightedEndpointGroup
{
Endpoints = new[]
{
new WeightedEndpoint
{
Uri = new Uri(HedgingEndpoint1)
},
new WeightedEndpoint
{
Uri = new Uri(HedgingEndpoint2)
}
}
};
}).ToArray();
});
}
return services;
}
}