Class: Rack::Throttle::SlidingWindow

Inherits:
Limiter
  • Object
show all
Defined in:
lib/rack/throttle/limiters/sliding_window.rb

Overview

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 burst, and the maximum allowed average traffic level.

Defined Under Namespace

Classes: LeakyBucket

Instance Attribute Summary

Attributes inherited from Limiter

#app, #matchers, #options

Instance Method Summary collapse

Methods inherited from Limiter

#blacklisted?, #call, #restricted_url?, #whitelisted?

Constructor Details

#initialize(app, options = {}) ⇒ SlidingWindow

Returns a new instance of SlidingWindow.

Parameters:

  • app (#call)
  • options (Hash{Symbol => Object}) (defaults to: {})

Options Hash (options):

  • :burst (Integer)

    5

  • :average (Float)

    1



14
15
16
17
18
# File 'lib/rack/throttle/limiters/sliding_window.rb', line 14

def initialize(app, options = {})
  super
  options[:burst] ||= 5
  options[:average] ||= 1
end

Instance Method Details

#allowed?(request) ⇒ Boolean

Returns ‘true` if the request conforms to the specified :average and :burst rules

Parameters:

  • request (Rack::Request)

Returns:

  • (Boolean)


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rack/throttle/limiters/sliding_window.rb', line 26

def allowed?(request)
  t1 = request_start_time(request)
  key = cache_key(request)
  bucket = Marshal.load(cache_get(key)) rescue nil
  bucket ||= LeakyBucket.new(options[:burst], options[:average])
  bucket.maximum, bucket.outflow = options[:burst], options[:average]
  bucket.leak!
  bucket.increment!
  allowed = !bucket.full?
  begin
    cache_set(key, Marshal.dump(bucket))
    allowed
  rescue StandardError => e
    allowed = true
    # If an error occurred while trying to update the timestamp stored
    # in the cache, we will fall back to allowing the request through.
    # This prevents the Rack application blowing up merely due to a
    # backend cache server (Memcached, Redis, etc.) being offline.
  end
end

#retry_afterFloat

Returns the number of seconds before the client is allowed to retry an HTTP request.

Returns:

  • (Float)


52
53
54
# File 'lib/rack/throttle/limiters/sliding_window.rb', line 52

def retry_after
  @retry_after ||= (1.0 / options[:average].to_f)
end