class HTTP::Cache

def cache_lookup(request)

Returns:
  • (HTTP::Response::Caching, nil) - the cached response for the request
def cache_lookup(request)
  return nil if request.skips_cache?
  rack_resp = metastore.lookup(request, entitystore)
  return if rack_resp.nil?
  HTTP::Response.new(
    rack_resp.status, "1.1", rack_resp.headers, stringify(rack_resp.body)
  ).caching
end

def get_response(req, options, request_performer)

Returns:
  • (Response) - the response to the request, either from the
def get_response(req, options, request_performer)
  cached_resp = cache_lookup(req)
  return cached_resp if cached_resp && !cached_resp.stale?
  # cache miss
  logger.debug { "Cache miss for <#{req.uri}>, making request" }
  actual_req = if cached_resp
                 req.conditional_on_changes_to(cached_resp)
               else
                 req
               end
  actual_resp = make_request(actual_req, options, request_performer)
  handle_response(cached_resp, actual_resp, req)
end

def handle_response(cached_resp, actual_resp, req)

updating the cache as appropriate
@returns [Response] the most useful of the responses after
def handle_response(cached_resp, actual_resp, req)
  if actual_resp.status.not_modified? && cached_resp
    logger.debug { "<#{req.uri}> not modified, using cached version." }
    cached_resp.validated!(actual_resp)
    store_in_cache(req, cached_resp)
    return cached_resp
  elsif req.cacheable? && actual_resp.cacheable?
    store_in_cache(req, actual_resp)
    return actual_resp
  else
    return actual_resp
  end
end

def initialize(opts)

Options Hash: (**opts)
  • :logger (Logger) -- logger to use
  • :entitystore (String) -- URL to the entitystore location
  • :metastore (String) -- URL to the metastore location
def initialize(opts)
  @metastore   = storage.resolve_metastore_uri(opts.fetch(:metastore))
  @entitystore = storage.resolve_entitystore_uri(opts.fetch(:entitystore))
  @logger = opts.fetch(:logger) { NullLogger.new }
end

def invalidate_cache(request)

Returns:
  • (nil) -
def invalidate_cache(request)
  metastore.invalidate(request, entitystore)
end

def make_request(req, options, request_performer)

Returns:
  • (HTTP::Response::Caching) - the actual response returned
def make_request(req, options, request_performer)
  req.sent_at = Time.now
  request_performer.call(req, options).caching.tap do |res|
    res.received_at  = Time.now
    res.requested_at = req.sent_at
  end
end

def perform(request, options, &request_performer)

Other tags:
    Yield: - on cache miss so that an actual

Returns:
  • (Response) - a cached response that is valid for the request or
def perform(request, options, &request_performer)
  req = request.caching
  invalidate_cache(req) if req.invalidates_cache?
  get_response(req, options, request_performer)
end

def storage

def storage
  @@storage ||= Rack::Cache::Storage.new # rubocop:disable Style/ClassVars
end

def store_in_cache(request, response)

Returns:
  • (nil) -
def store_in_cache(request, response)
  response.body = response.body.to_s
  metastore.store(request, response, entitystore)
  nil
end

def stringify(body)

def stringify(body)
  if body.respond_to?(:each)
    "".tap do |buf|
      body.each do |part|
        buf << part
      end
    end
  else
    body.to_s
  end
end