Class: NimbleThrottler

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/nimble_throttler.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeNimbleThrottler

Returns a new instance of NimbleThrottler.



12
13
14
15
16
17
# File 'lib/nimble_throttler.rb', line 12

def initialize
  @data = {}
  @cache_store = ActiveSupport::Cache::MemoryStore.new
  @default_period = 1.hours
  @default_limit = 100
end

Instance Attribute Details

#cache_storeObject

Returns the value of attribute cache_store.



9
10
11
# File 'lib/nimble_throttler.rb', line 9

def cache_store
  @cache_store
end

#dataObject

Returns the value of attribute data.



9
10
11
# File 'lib/nimble_throttler.rb', line 9

def data
  @data
end

#default_limitObject (readonly)

Returns the value of attribute default_limit.



10
11
12
# File 'lib/nimble_throttler.rb', line 10

def default_limit
  @default_limit
end

#default_periodObject (readonly)

Returns the value of attribute default_period.



10
11
12
# File 'lib/nimble_throttler.rb', line 10

def default_period
  @default_period
end

Class Method Details

.configure(&block) ⇒ Object



24
25
26
# File 'lib/nimble_throttler.rb', line 24

def configure(&block)
  class_eval(&block) if block_given?
end

.endpointsObject



32
33
34
# File 'lib/nimble_throttler.rb', line 32

def endpoints
  instance.data.keys
end

.exceed_limit?(req) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
46
47
# File 'lib/nimble_throttler.rb', line 43

def exceed_limit?(req)
  key, = key_and_expires_in(req)
  count = instance.cache_store.read(key).to_i
  count > instance.data[req.path][:limit].to_i
end

.expires_in(req) ⇒ Object



49
50
51
52
# File 'lib/nimble_throttler.rb', line 49

def expires_in(req)
  _, expires_in = key_and_expires_in(req)
  expires_in
end

.key_and_expires_in(req) ⇒ Object



54
55
56
57
58
59
60
# File 'lib/nimble_throttler.rb', line 54

def key_and_expires_in(req)
  period = (instance.data[req.path][:period] || instance.default_period).to_i
  epoch_time = Time.current.to_i
  expires_in = (period - (epoch_time % period) + 1)
  key = "req/ip:#{req.ip}:#{(epoch_time / period)}"
  [key, expires_in]
end

.throttle(endpoint, opts) ⇒ Object



28
29
30
# File 'lib/nimble_throttler.rb', line 28

def throttle(endpoint, opts)
  instance.add(endpoint, opts)
end

.throttle_for(req) ⇒ Object



36
37
38
39
40
41
# File 'lib/nimble_throttler.rb', line 36

def throttle_for(req)
  key, expires_in = key_and_expires_in(req)
  result = instance.cache_store.increment(key, 1, expires_in: expires_in)
  instance.cache_store.write(key, 1, expires_in: expires_in) if result.nil?
  result || 1
end

Instance Method Details

#add(key, value) ⇒ Object



19
20
21
# File 'lib/nimble_throttler.rb', line 19

def add(key, value)
  @data[key] = value
end