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.



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

def before_throttle_callback
  @before_throttle_callback
end

.cacheObject

Returns the value of attribute cache.



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

def cache
  @cache
end

.handlesObject Also known as: configurations

Returns the value of attribute handles.



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

def handles
  @handles
end

Class Method Details

.before_throttle(&blk) ⇒ Object



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

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)


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

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



131
132
133
134
# File 'lib/prop/limiter.rb', line 131

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



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

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

.read(&blk) ⇒ Object



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

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



120
121
122
123
# File 'lib/prop/limiter.rb', line 120

def reset(handle, key = nil, options = {})
  _options, cache_key = prepare(handle, key, options)
  @strategy.reset(cache_key)
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

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



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

def throttle(handle, key = nil, options = {}, &block)
  options, cache_key = prepare(handle, key, options)
  _throttle(handle, key, cache_key, options, &block).first
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



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

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

  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)


108
109
110
111
112
# File 'lib/prop/limiter.rb', line 108

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



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

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