| File: StandardResilienceBenchmark.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.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Polly; using Polly.Timeout; namespace Microsoft.Extensions.Http.Resilience.PerformanceTests; public class StandardResilienceBenchmark { private static readonly Uri _uri = new(HttpClientFactory.PrimaryEndpoint); private HttpClient _v7 = null!; private HttpClient _v8 = null!; private CancellationToken _cancellationToken; private static HttpRequestMessage Request => new(HttpMethod.Post, _uri); [GlobalSetup] public void Prepare() { _cancellationToken = new CancellationTokenSource().Token; var services = new ServiceCollection(); // The ResiliencePipelineBuilder added by Polly includes telemetry, which affects the results. // Since Polly v7 does not include telemetry either, let's disable the telemetry for v8 for fair results. services.TryAddTransient<ResiliencePipelineBuilder>(); services .AddHttpClient("v8") .ConfigurePrimaryHttpMessageHandler(() => new NoRemoteCallHandler()) .AddStandardResilienceHandler(); var builder = Policy.Handle<HttpRequestException>().Or<TimeoutRejectedException>().OrResult<HttpResponseMessage>(r => { var statusCode = (int)r.StatusCode; return statusCode >= 500 || r.StatusCode == HttpStatusCode.RequestTimeout || statusCode == 429; }); var policy = Policy.WrapAsync( Policy.TimeoutAsync<HttpResponseMessage>(3), builder.AdvancedCircuitBreakerAsync(0.1, TimeSpan.FromSeconds(30), 100, TimeSpan.FromSeconds(5)), builder.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1)), Policy.BulkheadAsync<HttpResponseMessage>(1000, 100), Policy.TimeoutAsync<HttpResponseMessage>(30)); services .AddHttpClient("v7") .ConfigurePrimaryHttpMessageHandler(() => new NoRemoteCallHandler()) .AddPolicyHandler(_ => policy); var factory = services.BuildServiceProvider().GetRequiredService<IHttpClientFactory>(); _v7 = factory.CreateClient("v7"); _v8 = factory.CreateClient("v8"); } [Benchmark(Baseline = true)] public Task<HttpResponseMessage> StandardPipeline_Polly_V7() { return _v7!.SendAsync(Request, _cancellationToken); } [Benchmark] public Task<HttpResponseMessage> StandardPipeline_Polly_V8() { return _v8!.SendAsync(Request, _cancellationToken); } [Benchmark] public HttpResponseMessage StandardPipeline_Polly_V8_Sync() { return _v8!.Send(Request, _cancellationToken); } }