Repository navigation
Circuit Breaker
Package: Carom.Extensions.
using Carom.Extensions;
var cushion = Cushion.ForService("payment-api")
.OpenAfter(failures: 5, trackingLast: 10)
.WithinLast(TimeSpan.FromMinutes(1))
.When(ex => ex is HttpRequestException)
.HalfOpenAfter(TimeSpan.FromSeconds(30));
var receipt = await CaromCushionExtensions.ShotAsync(() => payments.ChargeAsync(order), cushion);HalfOpenAfter ends the builder and returns the Cushion.
| Setting | Default | Rule |
|---|---|---|
OpenAfter(failures, trackingLast) |
5 of the last 10 |
failures at least 1, trackingLast at least failures
|
WithinLast |
1 minute | Must be positive. Older outcomes stop counting |
HalfOpenAfter |
30 seconds | Must be positive |
When |
every exception except OperationCanceledException
|
Decides what counts as the dependency's fault |
Without When, a bug in your own calling code, such as an ArgumentNullException, counts as a failure and can open the circuit on a healthy service.
- Closed: calls go through and outcomes are recorded.
-
Open: calls fail at once with
CircuitOpenException, which carriesServiceKey. -
HalfOpen: after
HalfOpenAfter, one caller is let through as a test. Success closes the circuit, failure opens it again. Other callers still getCircuitOpenExceptionwhile the test runs. If the test fails with an exceptionWhendoes not count, the result is inconclusive: the circuit goes back to Open and the delay restarts.
Cushion.GetState("payment-api") returns the current state, or null if no call has used that key yet. It creates nothing. The AspNetCore health check is built on it.
CaromCushionExtensions.ShotAsync wraps the whole retry sequence in the breaker. One logical call records one outcome however many attempts it took. The default retry predicate skips CircuitOpenException, so an open circuit is not retried.
State lives in a process-wide store keyed by service name. Two Cushion values with the same key share one circuit. Registering the same key with different settings throws InvalidOperationException that names the fields that differ. The store holds up to 1000 keys and evicts the least recently used when it grows past that.
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