lib/rack/throttle/limiters/sliding_window.rb in improved-rack-throttle-0.7.1 vs lib/rack/throttle/limiters/sliding_window.rb in improved-rack-throttle-0.8.0

- old
+ new

@@ -1,11 +1,11 @@ module Rack; module Throttle ## # This rate limiter strategy throttles the application with # a sliding window (implemented as a leaky bucket). It operates - # on second-level resolution. It takes :burst and :average - # options, which correspond to the maximum size of a traffic + # on second-level resolution. It takes :burst and :average + # options, which correspond to the maximum size of a traffic # burst, and the maximum allowed average traffic level. class SlidingWindow < Limiter ## # @param [#call] app # @param [Hash{Symbol => Object}] options @@ -16,22 +16,22 @@ options[:burst] ||= 5 options[:average] ||= 1 end ## - # Returns `true` if the request conforms to the + # Returns `true` if the request conforms to the # specified :average and :burst rules # # @param [Rack::Request] request # @return [Boolean] def allowed?(request) t1 = request_start_time(request) key = cache_key(request) bucket = cache_get(key) rescue nil bucket ||= LeakyBucket.new(options[:burst], options[:average]) bucket.maximum, bucket.outflow = options[:burst], options[:average] - bucket.leak! + bucket.leak! bucket.increment! allowed = !bucket.full? begin cache_set(key, bucket) allowed @@ -42,10 +42,19 @@ # This prevents the Rack application blowing up merely due to a # backend cache server (Memcached, Redis, etc.) being offline. end end + ## + # Returns the number of seconds before the client is allowed to retry an + # HTTP request. + # + # @return [Float] + def retry_after + @retry_after ||= (1.0 / options[:average].to_f) + end + ### # LeakyBucket is an internal class used to implement the # SlidingWindow limiter strategy. It is a (slightly tweaked) # implementation of the {http://en.wikipedia.org/wiki/Leaky_bucket # Leaky Bucket Algorithm}. @@ -65,10 +74,10 @@ t = Time.now time = t - last_touched loss = (outflow * time).to_f if loss > 0 @count -= loss - @last_touched = t + @last_touched = t end end def increment! @count = 0 if count < 0