Class: CMDx::CircuitBreaker
- Inherits:
-
Object
- Object
- CMDx::CircuitBreaker
- Defined in:
- lib/cmdx/circuit_breaker.rb
Overview
Declared via Task.circuit_breaker. After inputs resolve, consults shared
store counters before the retry_on loop; opens after repeated failures
and short-circuits until cool_off elapses.
Store keys come from StoreKey#task_key with class_scoped: true, plus
:failures and :open suffix segments (see StoreKey#compose).
Constant Summary collapse
- OPEN =
"open"- FAILURES =
"failures"
Instance Attribute Summary collapse
-
#key ⇒ Object
readonly
Returns the value of attribute key.
Class Method Summary collapse
-
.disabled ⇒ CircuitBreaker
Disabled configuration.
Instance Method Summary collapse
-
#build(new_key, new_options) ⇒ CircuitBreaker
Returns a new CircuitBreaker layering
new_optionsonto the current one. - #condition_if ⇒ Symbol, ...
- #condition_unless ⇒ Symbol, ...
- #cool_off ⇒ Integer
- #enabled? ⇒ Boolean
-
#initialize(key, options = EMPTY_HASH) ⇒ CircuitBreaker
constructor
A new instance of CircuitBreaker.
- #namespace ⇒ String
- #on_exceptions ⇒ Array<Class>
-
#on_open ⇒ Symbol
:failor:skip. -
#process(task) { ... } ⇒ Object
Runs the given block when the circuit is closed (or inactive).
- #threshold ⇒ Integer
- #window ⇒ Integer
Constructor Details
#initialize(key, options = EMPTY_HASH) ⇒ CircuitBreaker
Returns a new instance of CircuitBreaker.
39 40 41 42 |
# File 'lib/cmdx/circuit_breaker.rb', line 39 def initialize(key, = EMPTY_HASH) @key = key @options = .freeze end |
Instance Attribute Details
#key ⇒ Object (readonly)
Returns the value of attribute key.
24 25 26 |
# File 'lib/cmdx/circuit_breaker.rb', line 24 def key @key end |
Class Method Details
.disabled ⇒ CircuitBreaker
Returns disabled configuration.
18 19 20 |
# File 'lib/cmdx/circuit_breaker.rb', line 18 def disabled DISABLED end |
Instance Method Details
#build(new_key, new_options) ⇒ CircuitBreaker
Returns a new CircuitBreaker layering new_options onto the current one.
When new_key is non-nil it replaces the resolver; when new_key is
nil and only options change, the existing resolver is kept. When the
breaker was disabled and only options are passed, the resolver becomes
:class.
98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/cmdx/circuit_breaker.rb', line 98 def build(new_key, ) return self if new_key.nil? && .empty? merged_key = if new_key.nil? enabled? || .empty? ? @key : StoreKey::CLASS_KEY else new_key end = @options.merge() self.class.new(merged_key, ) end |
#condition_if ⇒ Symbol, ...
75 76 77 |
# File 'lib/cmdx/circuit_breaker.rb', line 75 def condition_if @options[:if] end |
#condition_unless ⇒ Symbol, ...
80 81 82 |
# File 'lib/cmdx/circuit_breaker.rb', line 80 def condition_unless @options[:unless] end |
#cool_off ⇒ Integer
55 56 57 |
# File 'lib/cmdx/circuit_breaker.rb', line 55 def cool_off @options[:cool_off] || 30 end |
#enabled? ⇒ Boolean
85 86 87 |
# File 'lib/cmdx/circuit_breaker.rb', line 85 def enabled? !key.nil? end |
#namespace ⇒ String
45 46 47 |
# File 'lib/cmdx/circuit_breaker.rb', line 45 def namespace @options[:namespace] || "cmdx:cb" end |
#on_exceptions ⇒ Array<Class>
65 66 67 |
# File 'lib/cmdx/circuit_breaker.rb', line 65 def on_exceptions @options.fetch(:on) { [StandardError] }.flatten end |
#on_open ⇒ Symbol
Returns :fail or :skip.
70 71 72 |
# File 'lib/cmdx/circuit_breaker.rb', line 70 def on_open @options[:on_open] || :fail end |
#process(task) { ... } ⇒ Object
When the circuit is open, signals fail! or skip! on task —
control does not return to the caller of #process.
Runs the given block when the circuit is closed (or inactive). Records failures for configured exception classes and clears the failure counter after a successful run.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/cmdx/circuit_breaker.rb', line 123 def process(task) return yield unless enabled? return yield unless Util.satisfied?(condition_if, condition_unless, task) store_key = StoreKey.task_key(task, namespace:, resolver: key, class_scoped: true) return yield if store_key.nil? open_key = StoreKey.compose(store_key, OPEN) failures_key = StoreKey.compose(store_key, FAILURES) open!(task, open_key) if circuit_open?(open_key) begin yield rescue StandardError => e record_failure(e, failures_key, open_key, task) raise e else clear_failures(failures_key, task) end end |
#threshold ⇒ Integer
50 51 52 |
# File 'lib/cmdx/circuit_breaker.rb', line 50 def threshold @options[:threshold] || 5 end |
#window ⇒ Integer
60 61 62 |
# File 'lib/cmdx/circuit_breaker.rb', line 60 def window @options[:window] || 60 end |