|
1 | | -using Microsoft.AspNetCore.Builder; |
2 | | -using Microsoft.AspNetCore.Mvc; |
3 | | -using System.Net.Http; |
4 | | -using System.Threading; |
5 | | - |
6 | 1 | var builder = WebApplication.CreateBuilder(args); |
7 | 2 |
|
8 | | -// Add services to the container. |
9 | | - |
10 | | -builder.Services.AddControllers(); |
11 | | - |
12 | 3 | builder.Services.AddHttpClient("TestClient", (sp, httpClient) => |
13 | 4 | { |
14 | 5 | var configuration = sp.GetRequiredService<IConfiguration>(); |
|
18 | 9 | httpClient.Timeout = TimeSpan.FromSeconds(timeoutSeconds); |
19 | 10 | }); |
20 | 11 |
|
21 | | -var app = builder.Build(); |
22 | | - |
23 | | -// Configure the HTTP request pipeline. |
24 | | - |
25 | | -app.UseHttpsRedirection(); |
26 | | - |
27 | | -app.UseAuthorization(); |
| 12 | +builder.Services.AddHttpClient("ResilientClient", httpClient => |
| 13 | +{ |
| 14 | + httpClient.BaseAddress = new Uri("http://localhost:5000"); |
| 15 | +}) |
| 16 | +.AddStandardResilienceHandler(options => |
| 17 | +{ |
| 18 | + options.AttemptTimeout.Timeout = TimeSpan.FromSeconds(2); |
| 19 | + options.TotalRequestTimeout.Timeout = TimeSpan.FromSeconds(8); |
| 20 | +}); |
28 | 21 |
|
29 | | -app.MapControllers(); |
| 22 | +var app = builder.Build(); |
30 | 23 |
|
31 | 24 | app.MapGet("/api/delay-4-seconds", async (CancellationToken cancellationToken) => await Task.Delay(TimeSpan.FromSeconds(4), cancellationToken)); |
32 | 25 |
|
|
36 | 29 |
|
37 | 30 | try |
38 | 31 | { |
39 | | - var response = await httpClient.GetAsync("/api/delay-4-seconds"); |
| 32 | + using var response = await httpClient.GetAsync("/api/delay-4-seconds"); |
40 | 33 |
|
41 | 34 | return Results.Ok(); |
42 | 35 | } |
|
53 | 46 |
|
54 | 47 | try |
55 | 48 | { |
56 | | - var response = await httpClient.GetAsync($"/api/delay-4-seconds", cancellationToken); |
| 49 | + using var response = await httpClient.GetAsync($"/api/delay-4-seconds", cancellationToken); |
57 | 50 |
|
58 | 51 | return Results.Ok(); |
59 | 52 | } |
|
71 | 64 |
|
72 | 65 | try |
73 | 66 | { |
74 | | - var response = await httpClient.GetAsync("/api/delay-4-seconds", tokenSource.Token); |
| 67 | + using var response = await httpClient.GetAsync("/api/delay-4-seconds", tokenSource.Token); |
75 | 68 |
|
76 | 69 | return Results.Ok(); |
77 | 70 | } |
|
83 | 76 | } |
84 | 77 | }); |
85 | 78 |
|
| 79 | +app.MapGet("/api/test-timeout-vs-cancellation", async (IHttpClientFactory httpClientFactory, CancellationToken cancellationToken) => |
| 80 | +{ |
| 81 | + var httpClient = httpClientFactory.CreateClient("TestClient"); |
| 82 | + |
| 83 | + try |
| 84 | + { |
| 85 | + using var response = await httpClient.GetAsync("/api/delay-4-seconds", cancellationToken); |
| 86 | + |
| 87 | + return Results.Ok(); |
| 88 | + } |
| 89 | + catch (OperationCanceledException ex) when (ex.InnerException is TimeoutException) |
| 90 | + { |
| 91 | + return Results.Text("The request timed out"); |
| 92 | + } |
| 93 | + catch (OperationCanceledException) |
| 94 | + { |
| 95 | + return Results.Text("The caller canceled the request"); |
| 96 | + } |
| 97 | +}); |
| 98 | + |
| 99 | +app.MapGet("/api/test-resilience-timeout", async (IHttpClientFactory httpClientFactory) => |
| 100 | +{ |
| 101 | + var httpClient = httpClientFactory.CreateClient("ResilientClient"); |
| 102 | + |
| 103 | + try |
| 104 | + { |
| 105 | + using var response = await httpClient.GetAsync("/api/delay-4-seconds"); |
| 106 | + |
| 107 | + return Results.Ok(); |
| 108 | + } |
| 109 | + catch (Exception ex) |
| 110 | + { |
| 111 | + return Results.Text($"{ex.GetType().Name} after {httpClient.Timeout}"); |
| 112 | + } |
| 113 | +}); |
| 114 | + |
86 | 115 | app.Run(); |
0 commit comments