module HTTParty::HTTPCache

Public Class Methods

included(base) click to toggle source
# File lib/httparty/httpcache.rb, line 17
def self.included(base)
  base.class_eval do
    alias_method_chain :perform, :caching
  end
end

Public Instance Methods

perform_with_caching() click to toggle source
# File lib/httparty/httpcache.rb, line 23
def perform_with_caching
  if cacheable?
    if response_in_cache?
      log_message("Retrieving response from cache")
      response_from(response_body_from_cache)
    else
      validate
      begin
        httparty_response = timeout(timeout_length) do
          perform_without_caching
        end
        if httparty_response.response.is_a?(Net::HTTPSuccess)
          log_message("Storing good response in cache")
          store_in_cache(httparty_response.body)
          store_backup(httparty_response.body)
          httparty_response
        else
          retrieve_and_store_backup(httparty_response)
        end
      rescue *exceptions
        retrieve_and_store_backup
      end
    end
  else
    log_message("Caching off")
    perform_without_caching
  end
end

Protected Instance Methods

backup_exists?() click to toggle source
# File lib/httparty/httpcache.rb, line 110
def backup_exists?
  redis.exists(backup_key) && redis.hexists(backup_key, uri_hash)
end
backup_key() click to toggle source
# File lib/httparty/httpcache.rb, line 102
def backup_key
  "api-cache:#{HTTPCache.apis[uri.host][:key_name]}"
end
backup_response() click to toggle source
# File lib/httparty/httpcache.rb, line 106
def backup_response
  redis.hget(backup_key, uri_hash)
end
cache_key_name() click to toggle source
# File lib/httparty/httpcache.rb, line 90
def cache_key_name
  @cache_key_name ||= "api-cache:#{HTTPCache.apis[uri.host][:key_name]}:#{uri_hash}"
end
cacheable?() click to toggle source
# File lib/httparty/httpcache.rb, line 54
def cacheable?
  HTTPCache.perform_caching && HTTPCache.apis.keys.include?(uri.host) &&
    http_method == Net::HTTP::Get
end
exceptions() click to toggle source
# File lib/httparty/httpcache.rb, line 140
def exceptions
  if (RUBY_VERSION.split('.')[1].to_i >= 9) && defined?(Psych::SyntaxError)
    [StandardError, Timeout::Error, Psych::SyntaxError]
  else
    [StandardError, Timeout::Error]
  end
end
log_message(message) click to toggle source
# File lib/httparty/httpcache.rb, line 127
def log_message(message)
  logger.info("[HTTPCache]: #{message} for #{normalized_uri} - #{uri_hash.inspect}") if logger
end
normalized_uri() click to toggle source
# File lib/httparty/httpcache.rb, line 77
def normalized_uri
  return @normalized_uri if @normalized_uri
  normalized_uri = uri.dup
  normalized_uri.query = sort_query_params(normalized_uri.query)
  normalized_uri.path.chop! if (normalized_uri.path =~ /\/$/)
  normalized_uri.scheme = normalized_uri.scheme.downcase
  @normalized_uri = normalized_uri.normalize.to_s
end
response_body_from_cache() click to toggle source
# File lib/httparty/httpcache.rb, line 114
def response_body_from_cache
  redis.get(cache_key_name)
end
response_from(response_body) click to toggle source
# File lib/httparty/httpcache.rb, line 59
def response_from(response_body)
  HTTParty::Response.new(self, OpenStruct.new(:body => response_body), parse_response(response_body))
end
response_in_cache?() click to toggle source
# File lib/httparty/httpcache.rb, line 98
def response_in_cache?
  redis.exists(cache_key_name)
end
retrieve_and_store_backup(httparty_response = nil) click to toggle source
# File lib/httparty/httpcache.rb, line 63
def retrieve_and_store_backup(httparty_response = nil)
  if backup_exists?
    log_message('using backup')
    response_body = backup_response
    store_in_cache(response_body, cache_stale_backup_time)
    response_from(response_body)
  elsif httparty_response
    httparty_response
  else
    log_message('No backup and bad response')
    raise NoResponseError, 'Bad response from API server or timeout occured and no backup was in the cache'
  end
end
sort_query_params(query) click to toggle source
# File lib/httparty/httpcache.rb, line 86
def sort_query_params(query)
  query.split('&').sort.join('&') unless query.blank?
end
store_backup(response_body) click to toggle source
# File lib/httparty/httpcache.rb, line 123
def store_backup(response_body)
  redis.hset(backup_key, uri_hash, response_body)
end
store_in_cache(response_body, expires = nil) click to toggle source
# File lib/httparty/httpcache.rb, line 118
def store_in_cache(response_body, expires = nil)
  redis.set(cache_key_name, response_body)
  redis.expire(cache_key_name, (expires || HTTPCache.apis[uri.host][:expire_in]))
end
timeout(seconds) { || ... } click to toggle source
# File lib/httparty/httpcache.rb, line 131
def timeout(seconds, &block)
  if defined?(SystemTimer)
    SystemTimer.timeout_after(seconds, &block)
  else
    options[:timeout] = seconds
    yield
  end
end
uri_hash() click to toggle source
# File lib/httparty/httpcache.rb, line 94
def uri_hash
  @uri_hash ||= Digest::MD5.hexdigest(normalized_uri)
end