Skip to content

feat: add trip() to force breaker into open state#2

Merged
abnegate merged 1 commit intomainfrom
feat/registry-and-trip
Apr 29, 2026
Merged

feat: add trip() to force breaker into open state#2
abnegate merged 1 commit intomainfrom
feat/registry-and-trip

Conversation

@abnegate
Copy link
Copy Markdown
Member

@abnegate abnegate commented Apr 29, 2026

Summary

Adds a single trip() method to CircuitBreaker that forces the breaker into the OPEN state, syncing through any configured cache adapter and recording state telemetry.

Why

  • Tests that exercise breaker-open behaviour (e.g. fallback paths in consumers) currently have to drive N synthetic failures through call() to flip state. trip() is the obvious shortcut.
  • Operationally, an admin endpoint that wants to disable a backend ("break the circuit on $namespace") needs a way to set OPEN without calling call().

Behaviour

  • Idempotent: calling trip() on an already-open breaker refreshes openedAt without re-recording a transition.
  • Cache-backed when an Adapter is configured (state, openedAt persisted).
  • Records the breaker.transitions counter and updates state gauges as transitionToOpen() does internally.

Test plan

  • Unit test: trips closed → open
  • Unit test: idempotent on already-open
  • Unit test: persists state through cache adapter
  • Unit test: emits transition + state telemetry

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 29, 2026

Greptile Summary

This PR adds a single trip() method to CircuitBreaker that forces the breaker into the OPEN state by delegating to the existing syncFromCache(), transitionToOpen(), and recordState() pipeline. The implementation is correct and idempotent — transitionToOpen()'s existing $from === $to guard in recordTransition() already prevents duplicate transition events on re-trips, cache writes are handled by the existing setters, and the five new tests cover the key paths (state change, call short-circuiting, idempotency, cache persistence, and telemetry).

Confidence Score: 5/5

Safe to merge; no logic or data-correctness bugs found in the implementation.

All findings are P2 (test coverage gaps). The production code correctly delegates to existing, well-tested internals with no new edge cases introduced.

tests/unit/CircuitBreakerTest.php — minor gaps in telemetry assertions for the two new test methods.

Important Files Changed

Filename Overview
src/CircuitBreaker/CircuitBreaker.php Adds trip() — a thin, correct public wrapper around the existing syncFromCache() + transitionToOpen() + recordState() pipeline; no logic bugs found.
tests/unit/CircuitBreakerTest.php Adds five trip() tests covering the core scenarios, but the idempotency test doesn't assert on telemetry and the telemetry test omits assertions on the failures/successes gauges emitted by recordState().

Reviews (3): Last reviewed commit: "feat: add trip() to force breaker into o..." | Re-trigger Greptile

Comment thread src/CircuitBreaker/Registry.php Outdated
Comment thread src/CircuitBreaker/CircuitBreaker.php
@abnegate abnegate force-pushed the feat/registry-and-trip branch from 0757603 to 35e0417 Compare April 29, 2026 01:57
@abnegate abnegate changed the title feat: trip() and Registry feat: add trip() to force breaker into open state Apr 29, 2026
Comment thread src/CircuitBreaker/CircuitBreaker.php
@abnegate abnegate force-pushed the feat/registry-and-trip branch from 35e0417 to 961e516 Compare April 29, 2026 02:22
Useful for tests that need to exercise breaker-open behaviour without
driving N failures through call(), and for operational manual breaks
(e.g. an admin endpoint disabling a backend). Idempotent: calling on
an already-open breaker refreshes openedAt without recording a transition.
@abnegate abnegate force-pushed the feat/registry-and-trip branch from 961e516 to 976f722 Compare April 29, 2026 02:23
@abnegate abnegate merged commit 86d3a66 into main Apr 29, 2026
6 checks passed
@abnegate abnegate deleted the feat/registry-and-trip branch April 29, 2026 02:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants