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:
- When
light1 and light2 check state, they may use different thresholds against the same shared failure data, causing inconsistent trip decisions
- Window calculations must accommodate the largest possible configuration to avoid data loss, wasting memory even when narrower windows would suffice
- One cannot determine which configuration "wins" when investigating circuit state
- 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
Currently, Stoplight allows multiple circuit breaker instances with identical names but different configurations to coexist:
Technical Implications:
light1andlight2check state, they may use different thresholds against the same shared failure data, causing inconsistent trip decisionsProposed Solution
Step 1 (Minor Release):
"Circuit 'api-gateway' has conflicting configurations. This will raise an error in v6.0"Step 2 (Major Release v6.0):
Stoplight::Error::ConfigurationConflictErroron conflict detectionStoplight("name").with_threshold(42)) which enables creating duplicate lightsLight#withmethod to prevent accidental duplicationBenefits