breaker_machines 0.9.2-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +184 -0
  4. data/ext/breaker_machines_native/extconf.rb +3 -0
  5. data/lib/breaker_machines/async_circuit.rb +47 -0
  6. data/lib/breaker_machines/async_support.rb +104 -0
  7. data/lib/breaker_machines/cascading_circuit.rb +177 -0
  8. data/lib/breaker_machines/circuit/async_state_management.rb +71 -0
  9. data/lib/breaker_machines/circuit/base.rb +59 -0
  10. data/lib/breaker_machines/circuit/callbacks.rb +135 -0
  11. data/lib/breaker_machines/circuit/configuration.rb +67 -0
  12. data/lib/breaker_machines/circuit/coordinated_state_management.rb +117 -0
  13. data/lib/breaker_machines/circuit/execution.rb +231 -0
  14. data/lib/breaker_machines/circuit/hedged_execution.rb +115 -0
  15. data/lib/breaker_machines/circuit/introspection.rb +93 -0
  16. data/lib/breaker_machines/circuit/native.rb +127 -0
  17. data/lib/breaker_machines/circuit/state_callbacks.rb +72 -0
  18. data/lib/breaker_machines/circuit/state_management.rb +59 -0
  19. data/lib/breaker_machines/circuit.rb +8 -0
  20. data/lib/breaker_machines/circuit_group.rb +153 -0
  21. data/lib/breaker_machines/console.rb +345 -0
  22. data/lib/breaker_machines/coordinated_circuit.rb +10 -0
  23. data/lib/breaker_machines/dsl/cascading_circuit_builder.rb +20 -0
  24. data/lib/breaker_machines/dsl/circuit_builder.rb +209 -0
  25. data/lib/breaker_machines/dsl/hedged_builder.rb +21 -0
  26. data/lib/breaker_machines/dsl/parallel_fallback_wrapper.rb +20 -0
  27. data/lib/breaker_machines/dsl.rb +283 -0
  28. data/lib/breaker_machines/errors.rb +71 -0
  29. data/lib/breaker_machines/hedged_async_support.rb +88 -0
  30. data/lib/breaker_machines/native_extension.rb +81 -0
  31. data/lib/breaker_machines/native_speedup.rb +10 -0
  32. data/lib/breaker_machines/registry.rb +243 -0
  33. data/lib/breaker_machines/storage/backend_state.rb +69 -0
  34. data/lib/breaker_machines/storage/base.rb +52 -0
  35. data/lib/breaker_machines/storage/bucket_memory.rb +176 -0
  36. data/lib/breaker_machines/storage/cache.rb +169 -0
  37. data/lib/breaker_machines/storage/fallback_chain.rb +294 -0
  38. data/lib/breaker_machines/storage/memory.rb +140 -0
  39. data/lib/breaker_machines/storage/native.rb +93 -0
  40. data/lib/breaker_machines/storage/null.rb +54 -0
  41. data/lib/breaker_machines/storage.rb +8 -0
  42. data/lib/breaker_machines/types.rb +41 -0
  43. data/lib/breaker_machines/version.rb +5 -0
  44. data/lib/breaker_machines.rb +200 -0
  45. data/lib/breaker_machines_native/breaker_machines_native.so +0 -0
  46. data/sig/README.md +74 -0
  47. data/sig/all.rbs +25 -0
  48. data/sig/breaker_machines/circuit.rbs +154 -0
  49. data/sig/breaker_machines/console.rbs +32 -0
  50. data/sig/breaker_machines/dsl.rbs +50 -0
  51. data/sig/breaker_machines/errors.rbs +24 -0
  52. data/sig/breaker_machines/interfaces.rbs +46 -0
  53. data/sig/breaker_machines/registry.rbs +30 -0
  54. data/sig/breaker_machines/storage.rbs +65 -0
  55. data/sig/breaker_machines/types.rbs +97 -0
  56. data/sig/breaker_machines.rbs +42 -0
  57. data/sig/manifest.yaml +5 -0
  58. metadata +224 -0
@@ -0,0 +1,200 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zeitwerk'
4
+ require 'active_support'
5
+ require 'active_support/core_ext'
6
+ require 'state_machines'
7
+ require_relative 'breaker_machines/errors'
8
+ require_relative 'breaker_machines/types'
9
+
10
+ loader = Zeitwerk::Loader.for_gem
11
+ loader.inflector.inflect('dsl' => 'DSL')
12
+ loader.ignore("#{__dir__}/breaker_machines/errors.rb")
13
+ loader.ignore("#{__dir__}/breaker_machines/types.rb")
14
+ loader.ignore("#{__dir__}/breaker_machines/console.rb")
15
+ loader.ignore("#{__dir__}/breaker_machines/async_support.rb")
16
+ loader.ignore("#{__dir__}/breaker_machines/hedged_async_support.rb")
17
+ loader.ignore("#{__dir__}/breaker_machines/circuit/async_state_management.rb")
18
+ loader.ignore("#{__dir__}/breaker_machines/native_speedup.rb")
19
+ loader.ignore("#{__dir__}/breaker_machines/native_extension.rb")
20
+ loader.ignore("#{__dir__}/breaker_machines/storage/native.rb")
21
+ loader.setup
22
+
23
+ # BreakerMachines provides a thread-safe implementation of the Circuit Breaker pattern
24
+ # for Ruby applications, helping to prevent cascading failures in distributed systems.
25
+ module BreakerMachines
26
+ # Global configuration class for BreakerMachines
27
+ class Configuration
28
+ attr_accessor :default_storage,
29
+ :default_timeout,
30
+ :default_reset_timeout,
31
+ :default_failure_threshold,
32
+ :log_events,
33
+ :fiber_safe
34
+
35
+ def initialize
36
+ @default_storage = :bucket_memory
37
+ @default_timeout = nil
38
+ @default_reset_timeout = 60.seconds
39
+ @default_failure_threshold = 5
40
+ @log_events = true
41
+ @fiber_safe = false
42
+ end
43
+ end
44
+
45
+ class << self
46
+ def loader
47
+ loader
48
+ end
49
+
50
+ def config
51
+ @config ||= Configuration.new
52
+ end
53
+
54
+ def configure
55
+ yield config
56
+ end
57
+
58
+ # Delegate config attributes to config object for backward compatibility
59
+ def default_storage
60
+ config.default_storage
61
+ end
62
+
63
+ def default_storage=(value)
64
+ config.default_storage = value
65
+ end
66
+
67
+ def default_timeout
68
+ config.default_timeout
69
+ end
70
+
71
+ def default_timeout=(value)
72
+ config.default_timeout = value
73
+ end
74
+
75
+ def default_reset_timeout
76
+ config.default_reset_timeout
77
+ end
78
+
79
+ def default_reset_timeout=(value)
80
+ config.default_reset_timeout = value
81
+ end
82
+
83
+ def default_failure_threshold
84
+ config.default_failure_threshold
85
+ end
86
+
87
+ def default_failure_threshold=(value)
88
+ config.default_failure_threshold = value
89
+ end
90
+
91
+ def log_events
92
+ config.log_events
93
+ end
94
+
95
+ def log_events=(value)
96
+ config.log_events = value
97
+ end
98
+
99
+ def fiber_safe
100
+ config.fiber_safe
101
+ end
102
+
103
+ def fiber_safe=(value)
104
+ config.fiber_safe = value
105
+ end
106
+
107
+ def setup_notifications
108
+ return unless config.log_events
109
+
110
+ ActiveSupport::Notifications.subscribe(/^breaker_machines\./) do |name, _start, _finish, _id, payload|
111
+ event_type = name.split('.').last
112
+ circuit_name = payload[:circuit]
113
+
114
+ case event_type
115
+ when 'opened'
116
+ logger&.warn "[BreakerMachines] Circuit '#{circuit_name}' opened"
117
+ when 'closed'
118
+ logger&.info "[BreakerMachines] Circuit '#{circuit_name}' closed"
119
+ when 'half_opened'
120
+ logger&.info "[BreakerMachines] Circuit '#{circuit_name}' half-opened"
121
+ end
122
+ end
123
+ end
124
+
125
+ def logger
126
+ @logger ||= ActiveSupport::Logger.new($stdout)
127
+ end
128
+
129
+ attr_writer :logger
130
+
131
+ # Centralized logging helper
132
+ # @param level [Symbol] log level (:debug, :info, :warn, :error)
133
+ # @param message [String] message to log
134
+ def log(level, message)
135
+ return unless config.log_events && logger
136
+
137
+ logger.public_send(level, "[BreakerMachines] #{message}")
138
+ end
139
+
140
+ def instrument(event, payload = {})
141
+ return unless config.log_events
142
+
143
+ ActiveSupport::Notifications.instrument("breaker_machines.#{event}", payload)
144
+ end
145
+
146
+ # Check if native extension is available
147
+ # @return [Boolean] true if native extension loaded successfully
148
+ def native_available?
149
+ @native_available || false
150
+ end
151
+
152
+ # Launch the interactive console
153
+ def console
154
+ require_relative 'breaker_machines/console'
155
+ Console.start
156
+ end
157
+
158
+ # Get the global registry
159
+ def registry
160
+ Registry.instance
161
+ end
162
+
163
+ # Register a circuit with the global registry
164
+ def register(circuit)
165
+ registry.register(circuit)
166
+ end
167
+
168
+ # Reset the registry and configurations (useful for testing)
169
+ def reset!
170
+ registry.clear
171
+ config.default_storage = :bucket_memory
172
+ config.default_timeout = nil
173
+ config.default_reset_timeout = 60.seconds
174
+ config.default_failure_threshold = 5
175
+ config.log_events = true
176
+ config.fiber_safe = false
177
+ end
178
+
179
+ # Returns the current monotonic time in seconds.
180
+ # Monotonic time is guaranteed to always increase and is not affected
181
+ # by system clock adjustments, making it ideal for measuring durations.
182
+ #
183
+ # @return [Float] current monotonic time in seconds
184
+ def monotonic_time
185
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
186
+ end
187
+ end
188
+
189
+ # Set up notifications on first use
190
+ setup_notifications if config.log_events
191
+ end
192
+
193
+ # Load optional native speedup after core is loaded
194
+ # Automatically loads if available, gracefully falls back to pure Ruby if not
195
+ begin
196
+ require_relative 'breaker_machines/native_speedup'
197
+ rescue LoadError
198
+ # Native extension not available, using pure Ruby backend
199
+ # This is expected on JRuby or when Cargo is not available
200
+ end
data/sig/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # BreakerMachines RBS Type Signatures
2
+
3
+ This directory contains RBS (Ruby type signatures) for the BreakerMachines gem.
4
+
5
+ ## Structure
6
+
7
+ - `breaker_machines.rbs` - Main module and configuration
8
+ - `breaker_machines/` - Type signatures for all classes and modules
9
+ - `circuit.rbs` - Circuit class and its modules
10
+ - `errors.rbs` - Error classes
11
+ - `storage.rbs` - Storage backends
12
+ - `dsl.rbs` - DSL module for including in classes
13
+ - `registry.rbs` - Global circuit registry
14
+ - `console.rbs` - Interactive console
15
+ - `types.rbs` - Common type aliases
16
+ - `interfaces.rbs` - Interface definitions
17
+
18
+ ## Usage
19
+
20
+ To use these type signatures in your project:
21
+
22
+ 1. Add to your `Steepfile`:
23
+ ```ruby
24
+ target :app do
25
+ signature "sig"
26
+ check "lib"
27
+
28
+ library "breaker_machines"
29
+ end
30
+ ```
31
+
32
+ 2. Or with RBS directly:
33
+ ```bash
34
+ rbs validate
35
+ ```
36
+
37
+ ## Type Checking Examples
38
+
39
+ ### Basic Circuit Usage
40
+ ```ruby
41
+ circuit = BreakerMachines::Circuit.new("api",
42
+ failure_threshold: 5,
43
+ reset_timeout: 30
44
+ )
45
+
46
+ result = circuit.call { api.fetch_data }
47
+ ```
48
+
49
+ ### DSL Usage
50
+ ```ruby
51
+ class MyService
52
+ include BreakerMachines::DSL
53
+
54
+ circuit :database do
55
+ threshold failures: 10, within: 60
56
+ reset_after 120
57
+ fallback { [] }
58
+ end
59
+ end
60
+ ```
61
+
62
+ ## Key Types
63
+
64
+ - `circuit_state` - `:open | :closed | :half_open`
65
+ - `storage_backend` - `:memory | :bucket_memory | :null | :redis`
66
+ - `circuit_options` - Configuration hash for circuits
67
+ - `event_record` - Structure for logged events
68
+
69
+ ## Interfaces
70
+
71
+ The type signatures define several interfaces:
72
+ - `_StorageBackend` - For custom storage implementations
73
+ - `_MetricsRecorder` - For custom metrics recording
74
+ - `_CircuitLike` - For circuit-compatible objects
data/sig/all.rbs ADDED
@@ -0,0 +1,25 @@
1
+ # Main entry point for BreakerMachines RBS types
2
+ #
3
+ # This file provides a complete type definition for the BreakerMachines gem,
4
+ # a Ruby implementation of the Circuit Breaker pattern.
5
+ #
6
+ # Usage:
7
+ # class MyService
8
+ # include BreakerMachines::DSL
9
+ #
10
+ # circuit :api_call do
11
+ # threshold failures: 5, within: 60
12
+ # reset_after 30
13
+ # fallback { |error| { error: "Service unavailable" } }
14
+ # end
15
+ #
16
+ # def fetch_data
17
+ # circuit(:api_call).call do
18
+ # # Your API call here
19
+ # end
20
+ # end
21
+ # end
22
+
23
+ # Import all type definitions
24
+ use BreakerMachines::*
25
+ use BreakerMachines::Storage::*
@@ -0,0 +1,154 @@
1
+ module BreakerMachines
2
+ class Circuit
3
+ include StateManagement
4
+ include Configuration
5
+ include Execution
6
+ include Introspection
7
+ include Callbacks
8
+
9
+ # Instance variables from Configuration module
10
+ @name: String
11
+ @config: Hash[Symbol, untyped]
12
+ @storage: _StorageBackend?
13
+ @metrics: _MetricsRecorder?
14
+ @opened_at: Concurrent::AtomicReference[Float?]
15
+ @half_open_attempts: Concurrent::AtomicFixnum
16
+ @half_open_successes: Concurrent::AtomicFixnum
17
+ @mutex: Concurrent::ReentrantReadWriteLock
18
+ @last_failure_at: Concurrent::AtomicReference[Float?]
19
+ @last_error: Concurrent::AtomicReference[StandardError?]
20
+
21
+ # State machine status (from StateManagement)
22
+ attr_reader status: (:open | :closed | :half_open)
23
+ end
24
+
25
+ module StateManagement
26
+ interface _StateManagementState
27
+ def status: () -> (:open | :closed | :half_open)
28
+ def status=: (:open | :closed | :half_open value) -> void
29
+ def status_name: () -> (:open | :closed | :half_open)
30
+ def open?: () -> bool
31
+ def closed?: () -> bool
32
+ def half_open?: () -> bool
33
+ def trip: () -> bool
34
+ def attempt_recovery: () -> bool
35
+ def reset: () -> bool
36
+ def force_open: () -> bool
37
+ def force_close: () -> bool
38
+ end
39
+
40
+ def self.included: (singleton(Circuit) base) -> void
41
+
42
+ private
43
+
44
+ def on_circuit_open: () -> void
45
+ def on_circuit_close: () -> void
46
+ def on_circuit_half_open: () -> void
47
+ def restore_status_from_storage: () -> void
48
+ def reset_timeout_elapsed?: () -> bool
49
+ def monotonic_time: () -> Float
50
+ end
51
+
52
+ module Configuration
53
+ extend ActiveSupport::Concern
54
+
55
+ interface _ConfigurationMethods
56
+ def name: () -> String
57
+ def config: () -> Hash[Symbol, untyped]
58
+ def opened_at: () -> Concurrent::AtomicReference[Float?]
59
+ end
60
+
61
+ type storage_type = Storage::Base | Storage::Memory | Storage::BucketMemory | Storage::Null
62
+ type metrics_type = untyped
63
+ type callback_type = Proc | nil
64
+ type fallback_type = Proc | Array[Proc | untyped] | untyped
65
+
66
+ type circuit_config = {
67
+ failure_threshold: Integer,
68
+ failure_window: Integer,
69
+ success_threshold: Integer,
70
+ timeout: Integer?,
71
+ reset_timeout: Integer,
72
+ reset_timeout_jitter: Float,
73
+ half_open_calls: Integer,
74
+ storage: storage_type?,
75
+ metrics: metrics_type?,
76
+ fallback: fallback_type?,
77
+ on_open: callback_type,
78
+ on_close: callback_type,
79
+ on_half_open: callback_type,
80
+ on_reject: callback_type,
81
+ exceptions: Array[Class],
82
+ owner: untyped
83
+ }
84
+
85
+ def initialize: (String name, ?circuit_config options) -> void
86
+
87
+ private
88
+
89
+ def default_config: () -> circuit_config
90
+ def create_default_storage: () -> storage_type
91
+ end
92
+
93
+ module Execution
94
+ def call: [T] () { () -> T } -> untyped
95
+ def wrap: [T] () { () -> T } -> untyped
96
+
97
+ private
98
+
99
+ def handle_open_status: () { () -> untyped } -> untyped
100
+ def handle_half_open_status: () { () -> untyped } -> untyped
101
+ def handle_closed_status: () { () -> untyped } -> untyped
102
+ def execute_call: () { () -> untyped } -> untyped
103
+ def reject_call: () -> untyped
104
+ def handle_success: () -> void
105
+ def handle_failure: () -> void
106
+ def failure_threshold_exceeded?: () -> bool
107
+ def success_threshold_reached?: () -> bool
108
+ def record_success: (Float duration) -> void
109
+ def record_failure: (Float duration, ?StandardError? error) -> void
110
+ end
111
+
112
+ module Introspection
113
+ type stats_hash = {
114
+ state: (:open | :closed | :half_open),
115
+ failure_count: Integer,
116
+ success_count: Integer,
117
+ last_failure_at: Float?,
118
+ opened_at: Float?,
119
+ half_open_attempts: Integer,
120
+ half_open_successes: Integer
121
+ }
122
+
123
+ type error_info = {
124
+ class: String,
125
+ message: String,
126
+ occurred_at: Float
127
+ }
128
+
129
+ type circuit_hash = {
130
+ name: String,
131
+ state: (:open | :closed | :half_open),
132
+ stats: stats_hash,
133
+ config: Hash[Symbol, untyped],
134
+ event_log: Array[untyped],
135
+ last_error: error_info?
136
+ }
137
+
138
+ def stats: () -> stats_hash
139
+ def configuration: () -> Hash[Symbol, untyped]
140
+ def event_log: (?limit: Integer) -> Array[untyped]?
141
+ def last_error: () -> StandardError?
142
+ def to_h: () -> circuit_hash
143
+ def summary: () -> String
144
+ def last_error_info: () -> error_info?
145
+ end
146
+
147
+ module Callbacks
148
+ private
149
+
150
+ def invoke_callback: (Symbol callback_name) -> void
151
+ def invoke_fallback: (StandardError error) -> untyped
152
+ def invoke_single_fallback: (Proc | untyped fallback, StandardError error) -> untyped
153
+ end
154
+ end
@@ -0,0 +1,32 @@
1
+ module BreakerMachines
2
+ class Console
3
+ @running: bool
4
+
5
+ def self.start: () -> void
6
+
7
+ def initialize: () -> void
8
+ def run: () -> void
9
+
10
+ private
11
+
12
+ def print_header: () -> void
13
+ def print_help: () -> void
14
+ def print_prompt: () -> void
15
+ def process_command: (String command) -> void
16
+
17
+ # Command methods
18
+ def list_circuits: () -> void
19
+ def show_stats: () -> void
20
+ def show_circuit: (String? name) -> void
21
+ def show_events: (String? name, Integer limit) -> void
22
+ def reset_circuit: (String? name) -> void
23
+ def force_open_circuit: (String? name) -> void
24
+ def force_close_circuit: (String? name) -> void
25
+ def generate_report: () -> void
26
+ def cleanup_registry: () -> void
27
+
28
+ # Utility methods
29
+ def colorize_state: (Symbol state) -> String
30
+ def colorize_event_type: (Symbol type) -> String
31
+ end
32
+ end
@@ -0,0 +1,50 @@
1
+ module BreakerMachines
2
+ module DSL
3
+ extend ActiveSupport::Concern
4
+
5
+ @instance_registries: Concurrent::Map[Class, Concurrent::Array[WeakRef[untyped]]]
6
+
7
+ module ClassMethods
8
+ @circuits: Hash[Symbol, Hash[Symbol, untyped]]
9
+
10
+ def instance_registry: () -> Concurrent::Array[WeakRef[untyped]]
11
+ def cleanup_instance_registry: () -> void
12
+ def circuit: (Symbol name) ?{ (CircuitBuilder) -> void } -> Hash[Symbol, untyped]
13
+ def circuits: () -> Hash[Symbol, Hash[Symbol, untyped]]
14
+ def circuit_definitions: () -> Hash[Symbol, Hash[Symbol, untyped]]
15
+ def reset_all_circuits: () -> void
16
+ def circuit_stats: () -> Hash[Symbol, { total: Integer, by_state: Hash[Symbol, Integer] }]
17
+ end
18
+
19
+ def circuit: (Symbol name) -> Circuit
20
+ def circuit_instances: () -> Hash[Symbol, Circuit]
21
+ def circuits_summary: () -> Hash[Symbol, String]
22
+ def circuits_report: () -> Hash[Symbol, untyped]
23
+ def reset_all_circuits: () -> void
24
+
25
+ class CircuitBuilder
26
+ attr_reader config: Hash[Symbol, untyped]
27
+
28
+ def initialize: () -> void
29
+
30
+ # Configuration methods
31
+ def threshold: (?failures: Integer?, ?within: Integer, ?successes: Integer?) -> void
32
+ def reset_after: (Integer duration, ?jitter: Float?) -> void
33
+ def timeout: (Integer duration) -> void
34
+ def half_open_requests: (Integer count) -> void
35
+ def storage: ((:memory | :bucket_memory | :redis | Class | Storage::Base) backend, **untyped) -> void
36
+ def metrics: (?untyped recorder) ?{ () -> void } -> void
37
+ def fallback: (?untyped value) ?{ (StandardError) -> untyped } -> void
38
+ def on_open: () { () -> void } -> void
39
+ def on_close: () { () -> void } -> void
40
+ def on_half_open: () { () -> void } -> void
41
+ def on_reject: () { () -> void } -> void
42
+ def notify: (Symbol service, ?String? url, ?events: Array[Symbol], **untyped options) -> void
43
+ def handle: (*Class exceptions) -> void
44
+
45
+ # Advanced features
46
+ def backends: (Array[untyped] list) -> void
47
+ def parallel_calls: (Integer count, ?timeout: Integer?) -> void
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,24 @@
1
+ module BreakerMachines
2
+ class Error < StandardError
3
+ end
4
+
5
+ class CircuitOpenError < Error
6
+ attr_reader circuit_name: String
7
+ attr_reader opened_at: Float?
8
+
9
+ def initialize: (String circuit_name, ?Float? opened_at) -> void
10
+ end
11
+
12
+ class CircuitTimeoutError < Error
13
+ attr_reader circuit_name: String
14
+ attr_reader timeout: Numeric
15
+
16
+ def initialize: (String circuit_name, Numeric timeout) -> void
17
+ end
18
+
19
+ class ConfigurationError < Error
20
+ end
21
+
22
+ class StorageError < Error
23
+ end
24
+ end
@@ -0,0 +1,46 @@
1
+ module BreakerMachines
2
+ # Interface for objects that can record metrics
3
+ interface _MetricsRecorder
4
+ def record_success: (String circuit_name, Float duration) -> void
5
+ def record_failure: (String circuit_name, Float duration) -> void
6
+ def record_rejection: (String circuit_name) -> void
7
+ end
8
+
9
+ # Interface for storage backends
10
+ interface _StorageBackend
11
+ def get_status: (String circuit_name) -> status_record?
12
+ def set_status: (String circuit_name, circuit_state status, ?Float? opened_at) -> void
13
+ def record_success: (String circuit_name, Float duration) -> void
14
+ def record_failure: (String circuit_name, Float duration) -> void
15
+ def success_count: (String circuit_name, Integer window_seconds) -> Integer
16
+ def failure_count: (String circuit_name, Integer window_seconds) -> Integer
17
+ def clear: (String circuit_name) -> void
18
+ def clear_all: () -> void
19
+ end
20
+
21
+ # Interface for advanced storage backends with event logging
22
+ interface _AdvancedStorageBackend
23
+ def record_success: (String circuit_name, ?Float? duration) -> void
24
+ def record_failure: (String circuit_name, ?Float? duration) -> void
25
+ def success_count: (String circuit_name, ?Integer? window) -> Integer
26
+ def failure_count: (String circuit_name, ?Integer? window) -> Integer
27
+ def get_status: (String circuit_name) -> Hash[Symbol, untyped]?
28
+ def set_status: (String circuit_name, circuit_state status, ?Float? opened_at) -> void
29
+ def clear: (String circuit_name) -> void
30
+ def record_event_with_details: (String circuit_name, event_type event_type, Float duration, ?Hash[Symbol, untyped] details) -> void
31
+ def event_log: (String circuit_name, ?Integer limit) -> Array[event_record]
32
+ end
33
+
34
+ # Interface for circuit-like objects
35
+ interface _CircuitLike
36
+ def name: () -> String
37
+ def call: () { () -> untyped } -> untyped
38
+ def wrap: () { () -> untyped } -> untyped
39
+ def status_name: () -> circuit_state
40
+ def open?: () -> bool
41
+ def closed?: () -> bool
42
+ def half_open?: () -> bool
43
+ def reset: () -> bool
44
+ def stats: () -> Hash[Symbol, untyped]
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ module BreakerMachines
2
+ class Registry
3
+ include Singleton
4
+
5
+ @circuits: Concurrent::Map[Integer, WeakRef[Circuit]]
6
+ @mutex: Mutex
7
+ @registration_count: Integer
8
+ @cleanup_interval: Integer
9
+
10
+ def initialize: () -> void
11
+
12
+ # Circuit management
13
+ def register: (Circuit circuit) -> void
14
+ def unregister: (Circuit circuit) -> void
15
+ def all_circuits: () -> Array[Circuit]
16
+ def find_by_name: (Symbol name) -> Array[Circuit]
17
+
18
+ # Reporting
19
+ def stats_summary: () -> { total: Integer, by_state: Hash[Symbol, Integer], by_name: Hash[Symbol, Integer] }
20
+ def detailed_report: () -> Array[Hash[Symbol, untyped]]
21
+
22
+ # Maintenance
23
+ def clear: () -> void
24
+ def cleanup_dead_references: () -> void
25
+
26
+ private
27
+
28
+ def cleanup_dead_references_unsafe: () -> void
29
+ end
30
+ end