Class: BreakerMachines::Storage::BucketMemory
- Defined in:
- lib/breaker_machines/storage/bucket_memory.rb
Overview
Efficient bucket-based memory storage implementation Uses fixed-size circular buffers for constant-time event counting
WARNING: This storage backend is NOT compatible with DRb (distributed Ruby) environments as memory is not shared between processes. Use Cache backend with an external cache store (Redis, Memcached) for distributed setups.
Constant Summary collapse
- BUCKET_SIZE =
1 second per bucket
1
Instance Method Summary collapse
- #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(**options) ⇒ BucketMemory
constructor
A new instance of BucketMemory.
- #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
Constructor Details
#initialize(**options) ⇒ BucketMemory
Returns a new instance of BucketMemory.
17 18 19 20 21 22 23 24 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 17 def initialize(**) super @circuits = Concurrent::Map.new @circuit_buckets = Concurrent::Map.new @event_logs = Concurrent::Map.new @bucket_count = [:bucket_count] || 300 # Default 5 minutes @max_events = [:max_events] || 100 end |
Instance Method Details
#clear(circuit_name) ⇒ Object
60 61 62 63 64 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 60 def clear(circuit_name) @circuits.delete(circuit_name) @circuit_buckets.delete(circuit_name) @event_logs.delete(circuit_name) end |
#clear_all ⇒ Object
66 67 68 69 70 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 66 def clear_all @circuits.clear @circuit_buckets.clear @event_logs.clear end |
#event_log(circuit_name, limit) ⇒ Object
91 92 93 94 95 96 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 91 def event_log(circuit_name, limit) events = @event_logs[circuit_name] return [] unless events events.last(limit).map(&:dup) end |
#failure_count(circuit_name, window_seconds) ⇒ Object
56 57 58 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 56 def failure_count(circuit_name, window_seconds) count_events(circuit_name, :failure, window_seconds) end |
#get_status(circuit_name) ⇒ Object
26 27 28 29 30 31 32 33 34 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 26 def get_status(circuit_name) circuit_data = @circuits[circuit_name] return nil unless circuit_data { status: circuit_data[:status], opened_at: circuit_data[:opened_at] } end |
#record_event_with_details(circuit_name, type, duration, error: nil, new_state: nil) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 72 def record_event_with_details(circuit_name, type, duration, error: nil, new_state: nil) events = @event_logs.compute_if_absent(circuit_name) { Concurrent::Array.new } event = { type: type, timestamp: monotonic_time, duration_ms: (duration * 1000).round(2) } event[:error_class] = error.class.name if error event[:error_message] = error. if error event[:new_state] = new_state if new_state events << event # Keep only the most recent events events.shift while events.size > @max_events end |
#record_failure(circuit_name, duration) ⇒ Object
48 49 50 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 48 def record_failure(circuit_name, duration) record_event(circuit_name, :failure, duration) end |
#record_success(circuit_name, duration) ⇒ Object
44 45 46 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 44 def record_success(circuit_name, duration) record_event(circuit_name, :success, duration) end |
#set_status(circuit_name, status, opened_at = nil) ⇒ Object
36 37 38 39 40 41 42 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 36 def set_status(circuit_name, status, opened_at = nil) @circuits[circuit_name] = { status: status, opened_at: opened_at, updated_at: monotonic_time } end |
#success_count(circuit_name, window_seconds) ⇒ Object
52 53 54 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 52 def success_count(circuit_name, window_seconds) count_events(circuit_name, :success, window_seconds) end |