http-resilience-and-outbound-callslisted
Install: claude install-skill Sarmkadan/dotnet-senior-skills
# HTTP Resilience and Outbound Calls
## Client construction
`new HttpClient()` per operation exhausts sockets (each instance owns a handler and its connections; disposed connections sit in TIME_WAIT). A single static `HttpClient` fixes that but caches DNS forever - it keeps calling the old IP after a failover. `IHttpClientFactory` solves both; it is the only acceptable construction in application code:
```csharp
services.AddHttpClient<PaymentsClient>(c =>
{
c.BaseAddress = new Uri(opts.BaseUrl);
c.Timeout = TimeSpan.FromSeconds(10);
});
```
Typed clients over named clients (compile-checked, config in one place). Two reminders from the DI skill: typed clients are transient - injecting one into a singleton freezes a single handler past its rotation window (stale DNS returns); and do not `using` the injected client.
## Timeouts: the non-negotiable
The review question for every outbound call: "what happens when this dependency hangs?" The default 100-second `HttpClient.Timeout` means the answer is "requests pile up for 100 seconds, then the thread pool and connection pool are gone" - a slow dependency takes you down harder than a dead one.
- Every client gets an explicit `Timeout` sized to the dependency's p99 plus margin - seconds, not the default.
- Per-attempt vs overall: `HttpClient.Timeout` caps the whole operation including retries inside a `DelegatingHandler`; the per-attempt timeout is a resilience-pipeline policy. You need both, and per-attempt < overall /