Class: BreakerMachines::Storage::FallbackChain
- Defined in:
- lib/breaker_machines/storage/fallback_chain.rb
Overview
Apocalypse-resistant storage backend that tries multiple storage backends in sequence Falls back to the next storage backend when the current one times out or fails
NOTE: For DRb (distributed Ruby) environments, only :cache backend with external cache stores (Redis, Memcached) will work properly. Memory-based backends (:memory, :bucket_memory) are incompatible with DRb as they don’t share state between processes.
Instance Attribute Summary collapse
-
#circuit_breaker_threshold ⇒ Object
readonly
Returns the value of attribute circuit_breaker_threshold.
-
#circuit_breaker_timeout ⇒ Object
readonly
Returns the value of attribute circuit_breaker_timeout.
-
#storage_configs ⇒ Object
readonly
Returns the value of attribute storage_configs.
-
#storage_instances ⇒ Object
readonly
Returns the value of attribute storage_instances.
-
#unhealthy_until ⇒ Object
readonly
Returns the value of attribute unhealthy_until.
Instance Method Summary collapse
- #cleanup! ⇒ Object
- #clear(circuit_name) ⇒ Object
- #clear_all ⇒ Object
- #event_log(circuit_name, limit) ⇒ Object
- #failure_count(circuit_name, window_seconds) ⇒ Object
- #get_status(circuit_name) ⇒ Object
-
#initialize(storage_configs) ⇒ FallbackChain
constructor
A new instance of FallbackChain.
- #record_event_with_details(circuit_name, type, duration, error: nil, new_state: nil) ⇒ Object
- #record_failure(circuit_name, duration) ⇒ Object
- #record_success(circuit_name, duration) ⇒ Object
- #set_status(circuit_name, status, opened_at = nil) ⇒ Object
- #success_count(circuit_name, window_seconds) ⇒ Object
- #with_timeout(_timeout_ms) ⇒ Object
Constructor Details
#initialize(storage_configs) ⇒ FallbackChain
Returns a new instance of FallbackChain.
14 15 16 17 18 19 20 21 22 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 14 def initialize(storage_configs, **) super(**) @storage_configs = normalize_storage_configs(storage_configs) @storage_instances = {} @unhealthy_until = {} @circuit_breaker_threshold = 3 # After 3 failures, mark backend as unhealthy @circuit_breaker_timeout = 30 # Keep marked as unhealthy for 30 seconds validate_configs! end |
Instance Attribute Details
#circuit_breaker_threshold ⇒ Object (readonly)
Returns the value of attribute circuit_breaker_threshold.
12 13 14 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 12 def circuit_breaker_threshold @circuit_breaker_threshold end |
#circuit_breaker_timeout ⇒ Object (readonly)
Returns the value of attribute circuit_breaker_timeout.
12 13 14 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 12 def circuit_breaker_timeout @circuit_breaker_timeout end |
#storage_configs ⇒ Object (readonly)
Returns the value of attribute storage_configs.
12 13 14 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 12 def storage_configs @storage_configs end |
#storage_instances ⇒ Object (readonly)
Returns the value of attribute storage_instances.
12 13 14 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 12 def storage_instances @storage_instances end |
#unhealthy_until ⇒ Object (readonly)
Returns the value of attribute unhealthy_until.
12 13 14 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 12 def unhealthy_until @unhealthy_until end |
Instance Method Details
#cleanup! ⇒ Object
70 71 72 73 74 75 76 77 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 70 def cleanup! storage_instances.each_value do |instance| instance.clear_all if instance.respond_to?(:clear_all) end storage_instances.clear @backend_failures&.clear unhealthy_until.clear end |
#clear(circuit_name) ⇒ Object
48 49 50 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 48 def clear(circuit_name) execute_with_fallback(:clear, circuit_name) end |
#clear_all ⇒ Object
52 53 54 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 52 def clear_all execute_with_fallback(:clear_all) end |
#event_log(circuit_name, limit) ⇒ Object
61 62 63 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 61 def event_log(circuit_name, limit) execute_with_fallback(:event_log, circuit_name, limit) end |
#failure_count(circuit_name, window_seconds) ⇒ Object
44 45 46 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 44 def failure_count(circuit_name, window_seconds) execute_with_fallback(:failure_count, circuit_name, window_seconds) end |
#get_status(circuit_name) ⇒ Object
24 25 26 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 24 def get_status(circuit_name) execute_with_fallback(:get_status, circuit_name) end |
#record_event_with_details(circuit_name, type, duration, error: nil, new_state: nil) ⇒ Object
56 57 58 59 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 56 def record_event_with_details(circuit_name, type, duration, error: nil, new_state: nil) execute_with_fallback(:record_event_with_details, circuit_name, type, duration, error: error, new_state: new_state) end |
#record_failure(circuit_name, duration) ⇒ Object
36 37 38 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 36 def record_failure(circuit_name, duration) execute_with_fallback(:record_failure, circuit_name, duration) end |
#record_success(circuit_name, duration) ⇒ Object
32 33 34 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 32 def record_success(circuit_name, duration) execute_with_fallback(:record_success, circuit_name, duration) end |
#set_status(circuit_name, status, opened_at = nil) ⇒ Object
28 29 30 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 28 def set_status(circuit_name, status, opened_at = nil) execute_with_fallback(:set_status, circuit_name, status, opened_at) end |
#success_count(circuit_name, window_seconds) ⇒ Object
40 41 42 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 40 def success_count(circuit_name, window_seconds) execute_with_fallback(:success_count, circuit_name, window_seconds) end |
#with_timeout(_timeout_ms) ⇒ Object
65 66 67 68 |
# File 'lib/breaker_machines/storage/fallback_chain.rb', line 65 def with_timeout(_timeout_ms) # FallbackChain doesn't use timeout directly - each backend handles its own yield end |