Explain the circuit breaker pattern.
A circuit breaker stops a caller from hammering a failing dependency. It tracks failures and moves between three states:
- Closed: calls pass through while failures stay under a threshold.
- Open: after too many failures, calls fail fast immediately without touching the dependency, giving it time to recover.
- Half-open: after a cool-down, a few trial calls are allowed. Success closes the breaker; failure reopens it.
CircuitBreaker cb = CircuitBreaker.ofDefaults("payment");
Supplier<String> decorated =
CircuitBreaker.decorateSupplier(cb, () -> callPayment());
It prevents resource exhaustion and cascading failures, because threads and connections are not tied up waiting on timeouts. Pair it with timeouts, limited retries with backoff and jitter, bulkheads to isolate pools, and a fallback such as a cached response or a graceful error. Without a timeout a circuit breaker is much less effective, since slow calls are as damaging as failed ones.