ZeroAlloc.Resilience
Source-generated, zero-allocation resilience policies for .NET.
Add [Retry], [Timeout], [RateLimit], and [CircuitBreaker] to an interface; the generator emits a proxy composing all policies in a fixed order, whatever order the attributes are written in, with no heap allocation on the happy path.
Quick example
[Retry(MaxAttempts = 3, BackoffMs = 200, Jitter = true)]
[Timeout(Ms = 5_000)]
[CircuitBreaker(MaxFailures = 5, ResetMs = 1_000, HalfOpenProbes = 1, Fallback = nameof(FetchFallback))]
public interface IExternalService
{
ValueTask<string> FetchAsync(string id, CancellationToken ct);
ValueTask<string> FetchFallback(string id, CancellationToken ct);
}
// Register — one line
services.AddExternalServiceResilience<ExternalServiceImpl>();
// Inject IExternalService — all policies are wired automatically
Contents
| Page | Description |
|---|---|
| Getting Started | Install, annotate an interface, register with DI |
| Attributes | [Retry], [Timeout], [RateLimit], [CircuitBreaker] reference |
| Source Generator | What the generator emits — annotated proxy example |
| Performance | Benchmark results and allocation profile |
Core Concepts
| Page | Description |
|---|---|
| Retry | Exponential backoff, jitter, per-attempt timeout, exhaustion behaviour |
| Timeout | Total timeout vs. per-attempt timeout, CTS lifecycle |
| Rate Limit | Token bucket, lock-free acquire, Shared vs Instance scope |
| Circuit Breaker | State machine, failure tracking, half-open probing, fallback |
| Execution Order | How policies compose: RateLimit → CB → Timeout → Retry |
Guides
| Page | Description |
|---|---|
| Fallback | Declare and implement circuit-breaker fallback methods |
| Method-Level Overrides | Per-method policy configuration |
| Result Return Types | Non-throwing failure path with Result, Result<T> and Result<T, E> |
| DI Registration | Generated extension method, overrides, manual construction |
Diagnostics
| ID | Severity | Description |
|---|---|---|
| ZR0001 | Error | Fallback method not found or signature mismatch |
| ZR0002 | Warning | Timeout configured but method has no CancellationToken |
| ZR0003 | Error | Policy cannot build a failure for this Result<T, E> error type |
| ZR0004 | Error | Invalid policy attribute value |
| ZR0006 | Warning | Policy not applied to method |
| ZR0007 | Error | Interface shape not supported by the resilience generator |
| ZR0008 | Error | Invalid ZeroAllocGeneratedAccessibility value |
| ZR0009 | Error | Retry member not found or signature mismatch |
| ZR0010 | Error / Warning | Result-aware retry cannot apply to method |
| ZR0011 | Warning | [RetryAttempt] has no effect without [Retry] |
| ZR0012 | Error | [RetryAttempt] parameter type not supported |
| ZR0013 | Warning | RethrowDeclined has no effect |
| ZR0014 | Error | Policy not supported on a stream method |
| ZR0015 | Warning | Policy not applied to a stream method |