class Airrecord::FaradayRateLimiter

Attributes

requests[RW]

Public Class Methods

new(app, requests_per_second: nil, sleeper: nil) click to toggle source
Calls superclass method
# File lib/airrecord/faraday_rate_limiter.rb, line 9
def initialize(app, requests_per_second: nil, sleeper: nil)
  super(app)
  @rps = requests_per_second
  @sleeper = sleeper || ->(seconds) { sleep(seconds) }
  @mutex = Mutex.new
  clear
end

Public Instance Methods

call(env) click to toggle source
# File lib/airrecord/faraday_rate_limiter.rb, line 17
def call(env)
  @mutex.synchronize do
    wait if too_many_requests_in_last_second?
    @app.call(env).on_complete do |_response_env|
      requests << Process.clock_gettime(Process::CLOCK_MONOTONIC)
      requests.shift if requests.size > @rps
    end
  end
end
clear() click to toggle source
# File lib/airrecord/faraday_rate_limiter.rb, line 27
def clear
  self.class.requests = []
end

Private Instance Methods

requests() click to toggle source
# File lib/airrecord/faraday_rate_limiter.rb, line 33
def requests
  self.class.requests
end
too_many_requests_in_last_second?() click to toggle source
# File lib/airrecord/faraday_rate_limiter.rb, line 37
def too_many_requests_in_last_second?
  return false unless @rps
  return false unless requests.size >= @rps

  window_span < 1.0
end
wait() click to toggle source
# File lib/airrecord/faraday_rate_limiter.rb, line 44
def wait
  # Time to wait until making the next request to stay within limits.
  # [1.1, 1.2, 1.3, 1.4, 1.5] => 1 - 0.4 => 0.6
  wait_time = 1.0 - window_span
  @sleeper.call(wait_time)
end
window_span() click to toggle source
1.1, 1.2, 1.3, 1.4, 1.5

> 1.5 - 1.1 => 0.4

# File lib/airrecord/faraday_rate_limiter.rb, line 52
def window_span
  requests.last - requests.first
end