Sha256: de7aba9a41449ae7e9691f4194b690d26086af74e673dd6315bd728d1015fecf

Contents?: true

Size: 1.96 KB

Versions: 2

Compression:

Stored size: 1.96 KB

Contents

require 'net/http'

# This class wraps up querying the API and remembers when each API was 
# last queried in case there is a limit to the number that can be made.
class APICache::API
  def initialize
    @query_times = {}
  end
  
  # Checks whether the API can be queried (i.e. whether retry_time has passed
  # since the last query to the API).
  # 
  # If retry_time is 0 then there is no limit on how frequently queries can
  # be made to the API.
  def queryable?(key, retry_time)
    if @query_times[key]
      if Time.now - @query_times[key] > retry_time
        APICache.logger.log "Queryable: true - retry_time has passed"
        true
      else
        APICache.logger.log "Queryable: false - queried too recently"
        false
      end
    else
      APICache.logger.log "Queryable: true - never used API before"
      true
    end
  end
  
  # Fetch data from the API.
  # 
  # If no block is given then the key is assumed to be a URL and which will
  # be queried expecting a 200 response. Otherwise the return value of the
  # block will be used.
  # 
  # If the block is unable to fetch the value from the API it should raise
  # APICache::Invalid.
  def get(key, timeout, &block)
    APICache.logger.log "Fetching data from the API"
    @query_times[key] = Time.now
    Timeout::timeout(timeout) do
      if block_given?
        # This should raise APICache::Invalid if it is not correct
        yield
      else
        get_via_http(key, timeout)
      end
    end
  rescue Timeout::Error, APICache::Invalid => e
    raise APICache::CannotFetch, e.message
  end
  
private
  
  def get_via_http(key, timeout)
    response = redirecting_get(key)
    case response
    when Net::HTTPSuccess
      # 2xx response code
      response.body
    else
      raise APICache::Invalid, "Invalid http response: #{response.code}"
    end
  end

  def redirecting_get(url)
    r = Net::HTTP.get_response(URI.parse(url))
    r.header['location'] ? redirecting_get(r.header['location']) : r
  end
end

Version data entries

2 entries across 2 versions & 2 rubygems

Version Path
mloughran-api_cache-0.1.2 lib/api_cache/api.rb
api_cache-0.1.2 lib/api_cache/api.rb