Download the PHP package rasuvaeff/resilience without Composer
On this page you can find all versions of the php package rasuvaeff/resilience. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download rasuvaeff/resilience
More information about rasuvaeff/resilience
Files in rasuvaeff/resilience
Package resilience
Short Description Resilience pipeline for PHP: composes retry, circuit breaker, and bulkhead in the correct order with the exception glue built in
License BSD-3-Clause
Homepage https://github.com/rasuvaeff/resilience
Informations about the package resilience
rasuvaeff/resilience
Resilience pipeline for PHP: composes rasuvaeff/retry,
rasuvaeff/circuit-breaker, and
rasuvaeff/bulkhead in the correct
order with the exception glue built in — the PHP analogue of Polly's
ResiliencePipeline / resilience4j's Decorators.
Русская версия
Using an AI coding assistant? Point it at llms.txt — a compact, self-contained API reference.
Why
The three leaf packages compose with plain closures — but composing them correctly requires glue that is easy to get wrong:
| Rule | Why |
|---|---|
Retry must stop on CircuitOpenException |
the circuit is open; more attempts are pointless and hostile to the downstream |
Retry must stop on BulkheadFullException (by default) |
saturation is not a transient error; blind re-attempts amplify overload |
Retry must stop on the breaker's StorageFailure |
an infrastructure outage is not a downstream verdict |
| Bulkhead innermost | a slot is held only while the callback runs — never during retry sleeps |
| Breaker outside the bulkhead | an open circuit rejects before a slot is even requested |
| Breaker inside vs outside retry | two legitimate orders with different semantics — see below |
Pipeline fixes the nesting order and appends the glue automatically,
without modifying the objects you pass in.
Requirements
- PHP 8.3+
rasuvaeff/retry^1.2.3,rasuvaeff/circuit-breaker^1.2,rasuvaeff/bulkhead^1.1.3,rasuvaeff/duration^1.1 (installed automatically)
Installation
Usage
The block below is executable — composer build runs it against the real
API via rasuvaeff/doc-exec, so the
// => values cannot rot. It uses the in-memory backends; in production you
point the bulkhead and the breaker at Redis/APCu stores — the pipeline code
does not change.
Every layer is optional, in any combination; an empty pipeline is a plain call (convenient for conditional assembly).
Nesting order
The default is retry(circuitBreaker(bulkhead(callback))):
- bulkhead innermost — a slot is occupied only while the callback actually runs, re-requested per attempt; retry sleeps consume zero concurrency budget;
- breaker around the bulkhead — an open circuit rejects before a slot is requested;
- retry outermost — with the glue predicates appended.
Breaker inside vs outside retry
BreakerInsideRetry (default) |
->breakerOutsideRetry() |
|
|---|---|---|
| One breaker outcome per | attempt | logical operation (whole retry loop) |
| Open circuit mid-loop | cuts the remaining attempts instantly | cannot cut the loop short |
| Transient blip fixed by a retry | still counts toward the failure ratio | never reaches the failure ratio |
| Choose when | the breaker should see real per-call health | the breaker should judge operations, not attempts |
isFailure receives |
the callback's own exception (and, breaker-wrapping-bulkhead, BulkheadFullException) |
what the retry loop throws — RetryExhausted on exhaustion (last downstream exception in its lastException), never the callback's exception directly |
Exception glue
build() appends stopIf predicates to a copy of your retry builder
(Retry is immutable — the instance you pass is never modified, and your
own stopIf/retryIf rules are preserved):
CircuitOpenException→ stop, always;StorageFailure(breaker's storage outage) → stop, always;BulkheadFullException→ stop by default; opt back in with->retryOnBulkheadFull()when a slot is expected to free within the backoff window.
All terminal exceptions surface unchanged — RetryExhausted,
CircuitOpenException, BulkheadFullException, StorageFailure, or the
callback's own exception. The optional fallback receives whichever of
them ended the call.
Public API
| Type | Description |
|---|---|
Pipeline |
Builder: for(name), bulkhead(), retry(), circuitBreaker(), breakerOutsideRetry(), retryOnBulkheadFull(), build() |
CompiledPipeline |
Immutable result: call(callable, ?callable $fallback): mixed, name() |
PipelineOrder |
Enum: BreakerInsideRetry, BreakerOutsideRetry |
Security
- The pipeline adds no I/O, no storage, and no exception types of its own;
the security posture is that of the leaf packages (see their READMEs —
notably the bulkhead's fail-closed store semantics and the breaker's
StorageFailurecontract). - With the breaker wrapping the bulkhead, a
BulkheadFullExceptionpasses through the breaker'sisFailureclassifier. Classify it as not-a-failure (Ignored) unless you deliberately want local saturation to open the circuit against a healthy downstream:
Examples
See examples/ — runnable scripts using the in-memory
backends of the leaf packages (no server needed).
Development
License
BSD-3-Clause. See LICENSE.md.
All versions of resilience with dependencies
rasuvaeff/bulkhead Version ^1.1.3
rasuvaeff/circuit-breaker Version ^1.2
rasuvaeff/duration Version ^1.1
rasuvaeff/retry Version ^1.2.3