module Unthrottle

Constants

VERSION

Attributes

config[RW]

Public Class Methods

api(timeout: 60) { || ... } click to toggle source

Run an api with rate limit

@param [Hash] opts input options @options opts [Integer] :timeout milli seconds to wait before you retry api

# File lib/Unthrottle.rb, line 65
def api(timeout: 60)
  sleep_time = 100/1000.0     # 100 millisecs
  Timeout::timeout(timeout) do # secs
    loop do
      count = self.register_api_call(@config.key)
      @config.logger.debug("Attempt api with #{count}")
      if count <= @config.limit
        @config.logger.debug("Going through with #{count}")
        yield                 # Call the block provided
        return
      end
      @config.logger.info("Rate limit hit! going to sleep with #{sleep_time}")
      sleep(sleep_time)       # milli secs
      # Geometric sleep progression for now
      sleep_time += sleep_time
    end
  end
end
configure() { |config| ... } click to toggle source
# File lib/Unthrottle.rb, line 29
def configure
  @config ||= Configuration.new
  yield(config) if block_given?
  # Create a redis connection if not provided with
  @config.redis ||=
    Redis.new(host: config.host, port: config.port,
              db: config.db)
  @config.logger ||= Logger.new(STDOUT)
  @config.logger.level = @config.log_level
end
register_api_call(key) click to toggle source

Register an Api Call in redis

@param key Api key name to register call with @return current count of this key

# File lib/Unthrottle.rb, line 44
def register_api_call(key)
  keyname = "Unthrottle:#{key}".to_sym # Puting key names in a namespace
  rate_limit_time = @config.rate_limit_time
  # This can possibly return nil and integer
  count = @config.redis.get(keyname).to_i
  # Run it as a redis transaction
  @config.redis.multi do |redis|
    redis.incr(keyname)
    # Set expire if this is a first time we call api
    if count == 0
      redis.expire(keyname, rate_limit_time)
    end
  end

  return count + 1
end

Private Instance Methods

api(timeout: 60) { || ... } click to toggle source

Run an api with rate limit

@param [Hash] opts input options @options opts [Integer] :timeout milli seconds to wait before you retry api

# File lib/Unthrottle.rb, line 65
def api(timeout: 60)
  sleep_time = 100/1000.0     # 100 millisecs
  Timeout::timeout(timeout) do # secs
    loop do
      count = self.register_api_call(@config.key)
      @config.logger.debug("Attempt api with #{count}")
      if count <= @config.limit
        @config.logger.debug("Going through with #{count}")
        yield                 # Call the block provided
        return
      end
      @config.logger.info("Rate limit hit! going to sleep with #{sleep_time}")
      sleep(sleep_time)       # milli secs
      # Geometric sleep progression for now
      sleep_time += sleep_time
    end
  end
end
configure() { |config| ... } click to toggle source
# File lib/Unthrottle.rb, line 29
def configure
  @config ||= Configuration.new
  yield(config) if block_given?
  # Create a redis connection if not provided with
  @config.redis ||=
    Redis.new(host: config.host, port: config.port,
              db: config.db)
  @config.logger ||= Logger.new(STDOUT)
  @config.logger.level = @config.log_level
end
register_api_call(key) click to toggle source

Register an Api Call in redis

@param key Api key name to register call with @return current count of this key

# File lib/Unthrottle.rb, line 44
def register_api_call(key)
  keyname = "Unthrottle:#{key}".to_sym # Puting key names in a namespace
  rate_limit_time = @config.rate_limit_time
  # This can possibly return nil and integer
  count = @config.redis.get(keyname).to_i
  # Run it as a redis transaction
  @config.redis.multi do |redis|
    redis.incr(keyname)
    # Set expire if this is a first time we call api
    if count == 0
      redis.expire(keyname, rate_limit_time)
    end
  end

  return count + 1
end