Repository navigation
Dependency Injection
using Carom;
using Carom.DependencyInjection;
services.AddCaromResilienceRegistry();
services.AddCaromResilience(all => all
.AddPipeline("payments", p => p
.AddTimeout(TimeSpan.FromSeconds(10))
.AddCircuitBreaker("payments-api", failureThreshold: 5, samplingWindow: 10)
.AddRetry(Bounce.Times(3).WithDelay(TimeSpan.FromMilliseconds(200)))
.AddBulkhead("payments-api", maxConcurrency: 20)));
// later
public PaymentService(IResiliencePipelineRegistry pipelines)
=> _pipeline = pipelines.GetPipeline("payments");
var receipt = await _pipeline.ExecuteAsync(ct => client.ChargeAsync(order, ct), cancellationToken);IResiliencePipelineRegistry is only registered by AddCaromResilienceRegistry(). Without it the pipelines are built but cannot be looked up by name. The registry collects every pipeline when it is first resolved, so the call order does not matter.
AddCaromResilience(services, name, configure) registers a single pipeline. GetPipeline throws KeyNotFoundException for an unknown name; TryGetPipeline returns false.
Strategies run in the order they are added, and the first one added is the outermost. In the example the timeout covers everything, the breaker records one outcome per call, the retry sits inside the breaker, and each attempt enters the bulkhead.
| Method | Behaviour |
|---|---|
AddRetry(int) / AddRetry(Bounce)
|
Core retry. The action gets the attempt token, so a Bounce timeout cancels it |
AddTimeout(TimeSpan) |
Throws TimeoutException when its own deadline passes. An OperationCanceledException from anything else, including your token, passes through unchanged |
AddCircuitBreaker |
See Circuit breaker |
AddBulkhead |
See Bulkhead |
AddRateLimit |
See Rate limiting |
AddFallback<TResult> |
Returns the fallback when the call fails, only when the pipeline's result type is TResult. The async path lets OperationCanceledException through; the sync path falls back on any exception |
The two timeout behaviours in AddRetry and AddTimeout were fixed in 2.0.1.
Circuit breaker, bulkhead and rate limit state is shared by key with the rest of the process, so a pipeline and a direct CaromCushionExtensions call with the same key share one circuit.
Written from the Carom source. The repository is the source of truth; if a page disagrees with the code, the code wins. Licensed MPL-2.0.
Core
Carom.Extensions
Integrations
Project