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



29
30
31
# File 'lib/prop/limiter.rb', line 29

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)


39
40
41
42
43
44
45
# File 'lib/prop/limiter.rb', line 39

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



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

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



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

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



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

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



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/prop/limiter.rb', line 65

def throttle(handle, key = nil, options = {})
  return false if disabled?

  options, cache_key = prepare(handle, key, options)
  counter = @strategy.increment(cache_key, options)

  if @strategy.compare_threshold?(counter, :>, options)
    before_throttle_callback &&
      before_throttle_callback.call(handle, key, options[:threshold], options[:interval])

    true
  else
    yield if block_given?
    false
  end
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

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



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

def throttle!(handle, key = nil, options = {})
  options, cache_key = prepare(handle, key, options)

  if throttle(handle, key, options)
    raise Prop::RateLimited.new(options.merge(cache_key: cache_key, handle: handle))
  end

  block_given? ? yield : @strategy.counter(cache_key, options)
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)


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

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