Skip to content

Enforce Circuit Breaker Name Uniqueness Across Configurations #464

@bolshakov

Description

@bolshakov

Currently, Stoplight allows multiple circuit breaker instances with identical names but different configurations to coexist:

light1 = Stoplight("api-gateway", threshold: 42, window: 300)
light2 = Stoplight("api-gateway", threshold: 12, window: 600)

Technical Implications:

  1. When light1 and light2 check state, they may use different thresholds against the same shared failure data, causing inconsistent trip decisions
  2. Window calculations must accommodate the largest possible configuration to avoid data loss, wasting memory even when narrower windows would suffice
  3. One cannot determine which configuration "wins" when investigating circuit state
  4. Library code must defensively handle configuration mismatches throughout the codebase, causing a maintenance burden.

Proposed Solution

Step 1 (Minor Release):

  • Detect configuration conflicts when a circuit is instantiated
  • Emit deprecation warning: "Circuit 'api-gateway' has conflicting configurations. This will raise an error in v6.0"
  • Track conflict via comparison of configuration hashes (threshold, timeout, window_size, etc.)
  • Add an opt-in configuration option to raise an error in case of conflicting configurations.

Step 2 (Major Release v6.0):

  • Raise Stoplight::Error::ConfigurationConflictError on conflict detection
    • Disallow creating circuit breakers with the same name but different configurations
    • Drop the old builder interface (Stoplight("name").with_threshold(42)) which enables creating duplicate lights
    • Require the name parameter for Light#with method to prevent accidental duplication
  • Remove defensive code that accommodates multiple configurations
  • Optimize window storage to match exact configuration needs

Benefits

  • Predictable behavior: One name = one configuration = consistent decisions
  • Memory efficiency: Store only the required window size
  • Code simplification: Remove configuration conflict handling logic, opens ways to use a more efficient implementation

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions