CLOSED
CLOSED = 'closed'
The circuit is closed: calls are allowed.
Stops a repair that keeps failing from being attempted forever.
Keyed on the finding code, because that is the identifier that survives a class rename and is the same key the ledger and the ladder use. A repair that has failed $threshold times in a row is almost certainly failing for a reason retrying will not fix, and each retry costs the same network round trip, the same lock, the same log line as the one before it.
Three states, and only three:
Only a recorded success clears the count. Time alone moves the circuit to half-open and no further, so a permanently broken code makes exactly one attempt per cooldown instead of flapping closed and hammering whatever it is failing against.
The clock is injected. A test that had to sleep for a five-minute cooldown would not be a test anyone runs, so time is a parameter here rather than a call to time() buried in a comparison.
State is in memory and dies with the process; durable state is the ledger's job.
__construct(int $threshold = 3, int $cooldown = 300, callable|null $clock = null) : mixed
Constructs the breaker.
| int | $threshold | Consecutive failures that open the circuit. |
| int | $cooldown | Seconds the circuit stays open, measured from the failure that opened it. |
| callable|null | $clock | Returns a unix timestamp as an int. NULL uses time(). |
When the threshold is below 1, or the cooldown is negative. A threshold of 0 would open every circuit before anything had failed.
state(string $code) : string
The state of one code's circuit right now.
Derived from the count and the clock on every call rather than stored, so a circuit cannot be left stale by nobody having asked about it during the cooldown.
| string | $code | The finding code. |
CLOSED, OPEN or HALF_OPEN.
recordFailure(string $code) : void
Records a failed attempt.
Every failure at or past the threshold re-stamps the open time. That is what makes a failed trial call restart the cooldown instead of leaving the circuit half-open and retrying on every sweep from then on.
| string | $code | The finding code the repair was for. |
recordSuccess(string $code) : void
Records a successful attempt, closing the circuit.
A success is the only thing that clears the count. Letting the cooldown alone clear it would turn a permanently broken code into one that retries $threshold times per cooldown.
| string | $code | The finding code the repair was for. |
reset(string $code) : void
Forgets a code entirely, as if it had never failed.
For an operator who has fixed the underlying cause and does not want to wait out a cooldown to find out. Not for the repair path; that reports what happened and lets the count decide.
| string | $code | The finding code to forget. |