Module: ThrottleMachines

Defined in:
lib/throttle_machines.rb,
lib/throttle_machines/engine.rb,
lib/throttle_machines/control.rb,
lib/throttle_machines/limiter.rb,
lib/throttle_machines/version.rb,
lib/throttle_machines/middleware.rb,
lib/throttle_machines/storage/base.rb,
lib/throttle_machines/storage/null.rb,
lib/throttle_machines/async_limiter.rb,
lib/throttle_machines/storage/redis.rb,
lib/throttle_machines/hedged_breaker.rb,
lib/throttle_machines/hedged_request.rb,
lib/throttle_machines/storage/memory.rb,
lib/throttle_machines/instrumentation.rb,
lib/throttle_machines/rack_middleware.rb,
lib/throttle_machines/throttled_error.rb,
lib/throttle_machines/dependency_error.rb,
lib/throttle_machines/controller_helpers.rb,
lib/throttle_machines/rack_middleware/track.rb,
lib/throttle_machines/rack_middleware/request.rb,
lib/throttle_machines/rack_middleware/safelist.rb,
lib/throttle_machines/rack_middleware/throttle.rb,
lib/throttle_machines/rack_middleware/blocklist.rb,
lib/throttle_machines/rack_middleware/fail2_ban.rb,
lib/throttle_machines/rack_middleware/allow2_ban.rb,
lib/throttle_machines/rack_middleware/configuration.rb

Defined Under Namespace

Modules: ControllerHelpers, Instrumentation, Storage Classes: AsyncLimiter, Configuration, Control, DependencyError, Engine, HedgedBreaker, HedgedRequest, Limiter, Middleware, RackMiddleware, ThrottledError

Constant Summary collapse

CircuitOpenError =
BreakerMachines::CircuitOpenError
RetryExhaustedError =
ChronoMachines::MaxRetriesExceededError
Breaker =

Back-compat wrapper: use BreakerMachines as the circuit implementation

BreakerMachines::Circuit
VERSION =
'0.1.2'

Class Method Summary collapse

Class Method Details

.break_circuit(key, failures:, timeout:, &block) ⇒ Object



83
84
85
86
87
88
89
90
91
# File 'lib/throttle_machines.rb', line 83

def break_circuit(key, failures:, timeout:, &block)
  # Delegate to BreakerMachines; use reset_timeout for open duration
  breaker = BreakerMachines::Circuit.new(
    key,
    failure_threshold: failures,
    reset_timeout: timeout
  )
  breaker.call(&block)
end

.configObject



39
40
41
# File 'lib/throttle_machines.rb', line 39

def config
  @config
end

.configure {|config| ... } ⇒ Object

Yields:



43
44
45
46
47
48
49
# File 'lib/throttle_machines.rb', line 43

def configure
  yield(config) if block_given?

  # Apply instrumentation settings
  Instrumentation.enabled = config.instrumentation_enabled
  Instrumentation.backend = config.instrumentation_backend if config.instrumentation_backend
end

.control(key, &block) ⇒ Object



72
73
74
75
76
# File 'lib/throttle_machines.rb', line 72

def control(key, &block)
  control = Control.new(key)
  control.instance_eval(&block) if block
  control
end

.hedged_requestObject

Convenience method



109
110
111
112
113
114
115
116
# File 'lib/throttle_machines/hedged_request.rb', line 109

def self.hedged_request(**, &)
  hedged = HedgedRequest.new(**)
  begin
    hedged.run(&)
  ensure
    hedged.shutdown
  end
end

.limit(key, limit:, period:, algorithm: :fixed_window, &block) ⇒ Object



78
79
80
81
# File 'lib/throttle_machines.rb', line 78

def limit(key, limit:, period:, algorithm: :fixed_window, &block)
  limiter = limiter(key, limit: limit, period: period, algorithm: algorithm)
  limiter.throttle!(&block)
end

.limiter(key, limit:, period:, algorithm: :fixed_window) ⇒ Object



102
103
104
# File 'lib/throttle_machines.rb', line 102

def limiter(key, limit:, period:, algorithm: :fixed_window)
  Limiter.new(key, limit: limit, period: period, algorithm: algorithm, storage: storage)
end

.reset!(key = nil) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/throttle_machines.rb', line 59

def reset!(key = nil)
  if key
    storage.clear("#{key}*")
  else
    storage.clear
    # Reset storage instance to force recreation with defaults
    config._storage_instance = nil
    # Re-apply instrumentation settings from the configuration
    Instrumentation.enabled = config.instrumentation_enabled
    Instrumentation.backend = config.instrumentation_backend
  end
end

.retry_with(max_attempts: 3, backoff: :exponential, &block) ⇒ Object



93
94
95
96
97
98
99
100
# File 'lib/throttle_machines.rb', line 93

def retry_with(max_attempts: 3, backoff: :exponential, &block)
  # Delegate to chrono_machines
  policy_options = {
    max_attempts: max_attempts,
    jitter_factor: backoff == :exponential ? 1.0 : 0.0
  }
  ChronoMachines.retry(policy_options, &block)
end

.storageObject



51
52
53
# File 'lib/throttle_machines.rb', line 51

def storage
  config._storage_instance ||= create_storage(config.default_storage)
end

.storage=(value) ⇒ Object



55
56
57
# File 'lib/throttle_machines.rb', line 55

def storage=(value)
  config._storage_instance = create_storage(value)
end