Class: Semian::CircuitBreaker
- Inherits:
-
Object
- Object
- Semian::CircuitBreaker
- Extended by:
- Forwardable
- Includes:
- CircuitBreakerBehaviour
- Defined in:
- lib/semian/circuit_breaker.rb
Overview
:nodoc:
Direct Known Subclasses
Instance Attribute Summary collapse
-
#error_threshold_timeout_enabled ⇒ Object
readonly
Returns the value of attribute error_threshold_timeout_enabled.
-
#error_timeout ⇒ Object
readonly
Returns the value of attribute error_timeout.
-
#exponential_backoff_error_timeout ⇒ Object
readonly
Returns the value of attribute exponential_backoff_error_timeout.
-
#exponential_backoff_initial_timeout ⇒ Object
readonly
Returns the value of attribute exponential_backoff_initial_timeout.
-
#half_open_resource_timeout ⇒ Object
readonly
Returns the value of attribute half_open_resource_timeout.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
Attributes included from CircuitBreakerBehaviour
#exceptions, #last_error, #name
Instance Method Summary collapse
- #acquire(resource = nil, scope: nil, adapter: nil, &block) ⇒ Object
- #destroy ⇒ Object
- #in_use? ⇒ Boolean
-
#initialize(name, exceptions:, success_threshold:, error_threshold:, error_timeout:, implementation:, half_open_resource_timeout: nil, error_threshold_timeout: nil, error_threshold_timeout_enabled: true, lumping_interval: 0, exponential_backoff_error_timeout: false, exponential_backoff_initial_timeout: 1, exponential_backoff_multiplier: 2) ⇒ CircuitBreaker
constructor
A new instance of CircuitBreaker.
- #mark_failed(error, scope: nil, adapter: nil) ⇒ Object
- #mark_success(scope: nil, adapter: nil) ⇒ Object
- #request_allowed? ⇒ Boolean
- #reset(scope: nil, adapter: nil) ⇒ Object
- #transition_to_half_open? ⇒ Boolean
Methods included from CircuitBreakerBehaviour
#closed?, #half_open?, #initialize_behaviour, #open?
Constructor Details
#initialize(name, exceptions:, success_threshold:, error_threshold:, error_timeout:, implementation:, half_open_resource_timeout: nil, error_threshold_timeout: nil, error_threshold_timeout_enabled: true, lumping_interval: 0, exponential_backoff_error_timeout: false, exponential_backoff_initial_timeout: 1, exponential_backoff_multiplier: 2) ⇒ CircuitBreaker
Returns a new instance of CircuitBreaker.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/semian/circuit_breaker.rb', line 22 def initialize(name, exceptions:, success_threshold:, error_threshold:, error_timeout:, implementation:, half_open_resource_timeout: nil, error_threshold_timeout: nil, error_threshold_timeout_enabled: true, lumping_interval: 0, exponential_backoff_error_timeout: false, exponential_backoff_initial_timeout: 1, exponential_backoff_multiplier: 2) initialize_behaviour(name: name) @exceptions = exceptions @success_count_threshold = success_threshold @error_count_threshold = error_threshold @error_threshold_timeout = error_threshold_timeout || error_timeout @error_threshold_timeout_enabled = error_threshold_timeout_enabled.nil? ? true : error_threshold_timeout_enabled @error_timeout = error_timeout @half_open_resource_timeout = half_open_resource_timeout @lumping_interval = lumping_interval @exponential_backoff_error_timeout = exponential_backoff_error_timeout @exponential_backoff_initial_timeout = exponential_backoff_initial_timeout @exponential_backoff_multiplier = exponential_backoff_multiplier @current_error_timeout = exponential_backoff_error_timeout ? exponential_backoff_initial_timeout : error_timeout @errors = implementation::SlidingWindow.new(max_size: @error_count_threshold) @successes = implementation::Integer.new @state = implementation::State.new reset end |
Instance Attribute Details
#error_threshold_timeout_enabled ⇒ Object (readonly)
Returns the value of attribute error_threshold_timeout_enabled.
12 13 14 |
# File 'lib/semian/circuit_breaker.rb', line 12 def error_threshold_timeout_enabled @error_threshold_timeout_enabled end |
#error_timeout ⇒ Object (readonly)
Returns the value of attribute error_timeout.
12 13 14 |
# File 'lib/semian/circuit_breaker.rb', line 12 def error_timeout @error_timeout end |
#exponential_backoff_error_timeout ⇒ Object (readonly)
Returns the value of attribute exponential_backoff_error_timeout.
12 13 14 |
# File 'lib/semian/circuit_breaker.rb', line 12 def exponential_backoff_error_timeout @exponential_backoff_error_timeout end |
#exponential_backoff_initial_timeout ⇒ Object (readonly)
Returns the value of attribute exponential_backoff_initial_timeout.
12 13 14 |
# File 'lib/semian/circuit_breaker.rb', line 12 def exponential_backoff_initial_timeout @exponential_backoff_initial_timeout end |
#half_open_resource_timeout ⇒ Object (readonly)
Returns the value of attribute half_open_resource_timeout.
12 13 14 |
# File 'lib/semian/circuit_breaker.rb', line 12 def half_open_resource_timeout @half_open_resource_timeout end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
12 13 14 |
# File 'lib/semian/circuit_breaker.rb', line 12 def state @state end |
Instance Method Details
#acquire(resource = nil, scope: nil, adapter: nil, &block) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/semian/circuit_breaker.rb', line 49 def acquire(resource = nil, scope: nil, adapter: nil, &block) transition_to_half_open(scope: scope, adapter: adapter) if transition_to_half_open? raise OpenCircuitError unless request_allowed? result = nil begin result = maybe_with_half_open_resource_timeout(resource, &block) rescue *@exceptions => error if !error.respond_to?(:marks_semian_circuits?) || error.marks_semian_circuits? mark_failed(error, scope: scope, adapter: adapter) end raise error else mark_success(scope: scope, adapter: adapter) end result end |
#destroy ⇒ Object
98 99 100 101 102 |
# File 'lib/semian/circuit_breaker.rb', line 98 def destroy @errors.destroy @successes.destroy @state.destroy end |
#in_use? ⇒ Boolean
104 105 106 |
# File 'lib/semian/circuit_breaker.rb', line 104 def in_use? !error_timeout_expired? && !@errors.empty? end |
#mark_failed(error, scope: nil, adapter: nil) ⇒ Object
76 77 78 79 80 81 82 83 |
# File 'lib/semian/circuit_breaker.rb', line 76 def mark_failed(error, scope: nil, adapter: nil) push_error(error) if closed? transition_to_open(scope: scope, adapter: adapter) if error_threshold_reached? elsif half_open? transition_to_open(scope: scope, adapter: adapter) end end |
#mark_success(scope: nil, adapter: nil) ⇒ Object
85 86 87 88 89 90 |
# File 'lib/semian/circuit_breaker.rb', line 85 def mark_success(scope: nil, adapter: nil) return unless half_open? @successes.increment transition_to_close(scope: scope, adapter: adapter) if success_threshold_reached? end |
#request_allowed? ⇒ Boolean
72 73 74 |
# File 'lib/semian/circuit_breaker.rb', line 72 def request_allowed? closed? || half_open? || transition_to_half_open? end |
#reset(scope: nil, adapter: nil) ⇒ Object
92 93 94 95 96 |
# File 'lib/semian/circuit_breaker.rb', line 92 def reset(scope: nil, adapter: nil) @errors.clear @successes.reset transition_to_close(scope: scope, adapter: adapter) end |
#transition_to_half_open? ⇒ Boolean
68 69 70 |
# File 'lib/semian/circuit_breaker.rb', line 68 def transition_to_half_open? open? && error_timeout_expired? && !half_open? end |