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 25 26 |
# 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 # Store creation time as anchor for relative timestamps (like Rust implementation) @start_time = BreakerMachines.monotonic_time end |
Instance Method Details
#clear(circuit_name) ⇒ Object
62 63 64 65 66 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 62 def clear(circuit_name) @circuits.delete(circuit_name) @circuit_buckets.delete(circuit_name) @event_logs.delete(circuit_name) end |
#clear_all ⇒ Object
68 69 70 71 72 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 68 def clear_all @circuits.clear @circuit_buckets.clear @event_logs.clear end |
#event_log(circuit_name, limit) ⇒ Object
93 94 95 96 97 98 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 93 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
58 59 60 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 58 def failure_count(circuit_name, window_seconds) count_events(circuit_name, :failure, window_seconds) end |
#get_status(circuit_name) ⇒ Object
28 29 30 31 32 33 34 35 36 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 28 def get_status(circuit_name) circuit_data = @circuits[circuit_name] return nil unless circuit_data BreakerMachines::Status.new( 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
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 74 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
50 51 52 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 50 def record_failure(circuit_name, duration) record_event(circuit_name, :failure, duration) end |
#record_success(circuit_name, duration) ⇒ Object
46 47 48 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 46 def record_success(circuit_name, duration) record_event(circuit_name, :success, duration) end |
#set_status(circuit_name, status, opened_at = nil) ⇒ Object
38 39 40 41 42 43 44 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 38 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
54 55 56 |
# File 'lib/breaker_machines/storage/bucket_memory.rb', line 54 def success_count(circuit_name, window_seconds) count_events(circuit_name, :success, window_seconds) end |