lib/weeter/limitator.rb in weeter-0.11.0 vs lib/weeter/limitator.rb in weeter-0.13.0
- old
+ new
@@ -1,13 +1,18 @@
require 'active_support/core_ext/numeric/time'
module Weeter
class Limitator
+ Result = Struct.new(:status, :limited_keys)
+ DO_NOT_LIMIT = :do_not_limit
+ INITIATE_LIMITING = :initiate_limiting
+ CONTINUE_LIMITING = :continue_limiting
+
module UNLIMITED
- def self.limit?(*args)
- false
+ def self.limit_status(*args)
+ DO_NOT_LIMIT
end
end
class TimeWindow
def initialize(options = {})
@@ -25,28 +30,40 @@
end
attr_accessor :lookup, :window, :max
def initialize(options = {})
- self.window= TimeWindow.new({
+ self.window = TimeWindow.new({
start: self.now,
duration: options.fetch(:duration)
})
self.max = options.fetch(:max)
flush
end
- def limit?(*keys)
+ def process(*keys)
ensure_correct_window
keys.each do |key|
increment(key)
end
- keys.any? { |key| exceeds_max?(key) }
+ result = Result.new
+ limited_keys = keys.select { |key| exceeds_max?(key) }
+ if limited_keys.any?
+ result[:limited_keys] = limited_keys
+ if limited_keys.any? { |key| exceeds_max_by_one?(key) }
+ result[:status] = INITIATE_LIMITING
+ else
+ result[:status] = CONTINUE_LIMITING
+ end
+ else
+ result[:status] = DO_NOT_LIMIT
+ end
+ result
end
protected
def now
@@ -57,9 +74,13 @@
lookup[key] += 1
end
def exceeds_max?(key)
lookup[key] > max
+ end
+
+ def exceeds_max_by_one?(key)
+ lookup[key] == max + 1
end
def ensure_correct_window
return unless window.over?(now)