class Redd::RateLimit

The class that handles rate limiting for reddit.

If you'd rather have an asynchronous or queue-based limiting, it's easy to write one yourself. A rate limiting class is any class that has an {#after_limit} method. The block returns a Faraday::Response object, so you can also extract the headers from the response and use those instead. To remove rate limiting entirely, follow the example below.

@example To remove rate limiting entirely, just burst forever.

rt = Redd::RateLimit.new
rt.burst!(Float::INFINITY)

Attributes

burst_length[RW]

@!attribute [rw] burst_length @return [Integer] The number of requests left to burst.

gap[RW]

@!attribute [rw] gap @return [Integer, Float] The minimum time between requests.

last_request[R]

@!attribute [r] last_request @return [Time] The time the last request was made.

remaining[R]

@!attribute [r] used @!attribute [r] remaining @!attribute [r] reset @return [Integer] The data from reddit's response headers.

reset[R]

@!attribute [r] used @!attribute [r] remaining @!attribute [r] reset @return [Integer] The data from reddit's response headers.

used[R]

@!attribute [r] used @!attribute [r] remaining @!attribute [r] reset @return [Integer] The data from reddit's response headers.

Public Class Methods

new(gap) click to toggle source

@param [Float, Integer] gap The minimum time between each request.

# File lib/redd/rate_limit.rb, line 34
def initialize(gap)
  # Some time ages ago, because we never made a request.
  @last_request = Time.at(0)
  @gap = gap
  @burst_length = 0
end

Public Instance Methods

after_limit() { || ... } click to toggle source

Sleep until 1 second has passed since the last request and perform the given request unless bursting.

@yield [Faraday::Response] A response. @return [Faraday::Response] The response.

# File lib/redd/rate_limit.rb, line 53
def after_limit
  response = yield
  update!(response)
  sleep(wait_time)
  response
end
burst!(times) click to toggle source

Don't sleep for the next few requests. @param [Integer] times The number of times to ignore limiting. @return [Integer] The total times rate limiting will be ignored.

# File lib/redd/rate_limit.rb, line 44
def burst!(times)
  @burst_length += times
end

Private Instance Methods

update!(response) click to toggle source

Update necessary info with each request. @param [Faraday::Response] response The response to the request made.

# File lib/redd/rate_limit.rb, line 64
def update!(response)
  @last_request_time = Time.now
  %w(used remaining reset).each do |type|
    value = response.headers["x-ratelimit-#{type}"]
    instance_variable_set("@#{type}", value.to_i) unless value.nil?
  end
end
wait_time() click to toggle source

@return [Float, Integer] The number of seconds to sleep.

# File lib/redd/rate_limit.rb, line 73
def wait_time
  if @burst_length > 0 && @remaining > 0
    # Don't sleep if we are in burst mode.
    @burst_length -= 1
    0
  elsif @reset.nil? || @remaining.nil?
    # Just guess if no headers were given (max 1 sec after last request).
    time = @last_request_time - Time.now + @gap
    time > 0 ? time : 0
  else
    # Most cases, spread out requests over available time.
    @reset.to_f / (@gap * @remaining + 1)
  end
end