12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
# File 'lib/redis-throttler/model.rb', line 12
def throttle(key, opts = {})
klass = self.to_s.downcase
key = "#{key.to_s}"
subject = opts[:by] || :id
limit = opts[:limit] || RedisThrottler.default_limit
threshold = opts[:for] || RedisThrottler.default_threshold
interval = opts[:interval] || ([threshold,120].max)/120
bucket_span = threshold * 2
throttler = RedisThrottler::Base.new("#{klass}:#{key}", bucket_interval: interval, bucket_span: bucket_span)
@limits[key] = { :limit => limit, :threshold => threshold }
method = "#{key}_throttler"
%w(limits limits?).each do |string|
define_singleton_method(string) { string.include?('?') || @limits }
define_method(string) { string.include?('?') || self.class.instance_variable_get(:@limits)}
end
methods = {
:exceeded? => proc { |to_call, within| "#{method}.exceeded? \"#{to_call}\", threshold: #{limit}, interval: #{within}" },
:increment => proc { |to_call| "#{method}.add(\"#{to_call}\")" },
:count => proc { |to_call, within| "#{method}.count(\"#{to_call}\", #{within})" }
}
define_singleton_method(method) { throttler }
define_method(method) { self.class.send method }
methods.each do |magic, meth|
define_singleton_method("#{key}_#{magic.to_s}") { |id, within = threshold| eval meth.call(id, within) }
define_method("#{key}_#{magic.to_s}") { |within = threshold| eval meth.call("#{self.send subject}", within) }
end
end
|