Class: Prop::Limiter

Inherits:
Object
  • Object
show all
Defined in:
lib/prop/limiter.rb

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.before_throttle_callbackObject

Returns the value of attribute before_throttle_callback.



12
13
14
# File 'lib/prop/limiter.rb', line 12

def before_throttle_callback
  @before_throttle_callback
end

.cacheObject

Returns the value of attribute cache.



12
13
14
# File 'lib/prop/limiter.rb', line 12

def cache
  @cache
end

.handlesObject Also known as: configurations

Returns the value of attribute handles.



12
13
14
# File 'lib/prop/limiter.rb', line 12

def handles
  @handles
end

Class Method Details

.before_throttle(&blk) ⇒ Object



38
39
40
# File 'lib/prop/limiter.rb', line 38

def before_throttle(&blk)
  self.before_throttle_callback = blk
end

.configure(handle, defaults) ⇒ Object

Public: Registers a handle for rate limiting

handle - the name of the handle you wish to use in your code, e.g. :login_attempt defaults - the settings for this handle, e.g. { threshold: 5, interval: 5.minutes }

Raises Prop::RateLimited if the number if the threshold for this handle has been reached

Raises:

  • (ArgumentError)


48
49
50
51
52
53
54
# File 'lib/prop/limiter.rb', line 48

def configure(handle, defaults)
  raise ArgumentError.new("Invalid threshold setting") unless defaults[:threshold].to_i > 0
  raise ArgumentError.new("Invalid interval setting")  unless defaults[:interval].to_i > 0

  self.handles ||= {}
  self.handles[handle] = defaults
end

.count(handle, key = nil, options = {}) ⇒ Object Also known as: query

Public: Counts the number of times the given handle/key combination has been hit in the current window

handle - the throttle identifier key - the associated key

Returns a count of hits in the current window



133
134
135
136
# File 'lib/prop/limiter.rb', line 133

def count(handle, key = nil, options = {})
  options, cache_key = prepare(handle, key, options)
  @strategy.counter(cache_key, options)
end

.disabled(&block) ⇒ Object

Public: Disables Prop for a block of code

block - a block of code within which Prop will not raise



59
60
61
62
63
64
# File 'lib/prop/limiter.rb', line 59

def disabled(&block)
  @disabled = true
  yield
ensure
  @disabled = false
end

.read(&blk) ⇒ Object



14
15
16
# File 'lib/prop/limiter.rb', line 14

def read(&blk)
  raise "Use .cache = "
end

.reset(handle, key = nil, options = {}) ⇒ Object

Public: Resets a specific throttle

handle - the throttle identifier key - the associated key

Returns nothing



122
123
124
125
# File 'lib/prop/limiter.rb', line 122

def reset(handle, key = nil, options = {})
  _options, cache_key = prepare(handle, key, options)
  @strategy.reset(cache_key)
end

.throttle(handle, key = nil, options = {}) ⇒ Object

Public: Records a single action for the given handle/key combination.

handle - the registered handle associated with the action key - a custom request specific key, e.g. [ account.id, “download”, request.remote_ip ] options - request specific overrides to the defaults configured for this handle (optional) a block of code that this throttle is guarding

Returns true if the threshold for this handle has been reached, else returns false



74
75
76
77
78
# File 'lib/prop/limiter.rb', line 74

def throttle(handle, key = nil, options = {})
  options, cache_key = prepare(handle, key, options)
  throttled = _throttle(handle, key, cache_key, options).first
  block_given? && !throttled ? yield : throttled
end

.throttle!(handle, key = nil, options = {}, &block) ⇒ Object

Public: Records a single action for the given handle/key combination.

handle - the registered handle associated with the action key - a custom request specific key, e.g. [ account.id, “download”, request.remote_ip ] options - request specific overrides to the defaults configured for this handle (optional) a block of code that this throttle is guarding

Raises Prop::RateLimited if the threshold for this handle has been reached Returns the value of the block if given a such, otherwise the current count of the throttle



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/prop/limiter.rb', line 89

def throttle!(handle, key = nil, options = {}, &block)
  options, cache_key = prepare(handle, key, options)
  throttled, counter = _throttle(handle, key, cache_key, options)

  if throttled
    raise Prop::RateLimited.new(options.merge(
      cache_key: cache_key,
      handle: handle,
      first_throttled: (throttled == :first_throttled)
    ))
  end

  block_given? ? yield : counter
end

.throttled?(handle, key = nil, options = {}) ⇒ Boolean

Public: Is the given handle/key combination currently throttled ?

handle - the throttle identifier key - the associated key

Returns true if a call to ‘throttle!` with same parameters would raise, otherwise false

Returns:

  • (Boolean)


110
111
112
113
114
# File 'lib/prop/limiter.rb', line 110

def throttled?(handle, key = nil, options = {})
  options, cache_key = prepare(handle, key, options)
  counter = @strategy.counter(cache_key, options)
  @strategy.compare_threshold?(counter, :>=, options)
end

.write(&blk) ⇒ Object



18
19
20
# File 'lib/prop/limiter.rb', line 18

def write(&blk)
  raise "Use .cache = "
end