lib/prop/limiter.rb in prop-2.0.4 vs lib/prop/limiter.rb in prop-2.1.0
- old
+ new
@@ -68,25 +68,13 @@
# 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
- def throttle(handle, key = nil, options = {})
- return false if disabled?
-
+ def throttle(handle, key = nil, options = {}, &block)
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
+ _throttle(handle, key, cache_key, options, &block).first
end
# Public: Records a single action for the given handle/key combination.
#
# handle - the registered handle associated with the action
@@ -94,18 +82,23 @@
# 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
- def throttle!(handle, key = nil, options = {})
+ def throttle!(handle, key = nil, options = {}, &block)
options, cache_key = prepare(handle, key, options)
+ throttled, counter = _throttle(handle, key, cache_key, options, &block)
- if throttle(handle, key, options)
- raise Prop::RateLimited.new(options.merge(cache_key: cache_key, handle: handle))
+ if throttled
+ raise Prop::RateLimited.new(options.merge(
+ cache_key: cache_key,
+ handle: handle,
+ first_throttled: (throttled == :first_throttled)
+ ))
end
- block_given? ? yield : @strategy.counter(cache_key, options)
+ block_given? ? yield : counter
end
# Public: Is the given handle/key combination currently throttled ?
#
# handle - the throttle identifier
@@ -145,9 +138,31 @@
@handles ||= {}
end
alias :configurations :handles
private
+
+ def _throttle(handle, key, cache_key, options)
+ return [false, @strategy.zero_counter] if disabled?
+
+ 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])
+
+ result = if options[:first_throttled] && @strategy.first_throttled?(counter, options)
+ :first_throttled
+ else
+ true
+ end
+
+ [result, counter]
+ else
+ yield if block_given?
+ [false, counter]
+ end
+ end
def disabled?
!!@disabled
end