Class: Faraday::ObjectCache

Inherits:
Middleware
  • Object
show all
Defined in:
lib/ontologies_api_client/middleware/faraday-object-cache.rb

Defined Under Namespace

Classes: CompressedMemcache

Instance Method Summary collapse

Constructor Details

#initialize(app, *arguments) ⇒ ObjectCache

Returns a new instance of ObjectCache.



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/ontologies_api_client/middleware/faraday-object-cache.rb', line 15

def initialize(app, *arguments)
  super(app)

  if arguments.last.is_a? Hash
    options = arguments.pop
    @logger = options.delete(:logger)
  else
    options = arguments
  end

  @store = options[:store] || ActiveSupport::Cache.lookup_store(store, options)
end

Instance Method Details

#call(env) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ontologies_api_client/middleware/faraday-object-cache.rb', line 28

def call(env)
  # Add if newer than last modified statement to headers
  request_key = cache_key_for(create_request(env))
  last_modified_key = "LM::#{request_key}"
  last_retrieved_key = "LR::#{request_key}"

  # If we made the last request within the expiry
  if cache_exist?(last_retrieved_key) && cache_exist?(request_key)
    puts "DEBUG not expired #{env[:url].to_s}" if $CACHE_DEBUG
    cached_item = cache_read(request_key)
    ld_obj = cached_item.is_a?(Hash) && cached_item.key?(:ld_obj) ? cached_item[:ld_obj] : cached_item
    env[:status] = 304
    cached_response = ObjectCacheResponse.new(env)
    cached_response.parsed_body = ld_obj
    return cached_response
  end

  last_modified = cache_read(last_modified_key)
  headers = env[:request_headers]
  puts "DEBUG last modified: " + last_modified.to_s if last_modified && $CACHE_DEBUG
  headers['If-Modified-Since'] = last_modified if last_modified

  @app.call(env).on_complete do |response_env|
    # Only cache get and head requests
    if [:get, :head].include?(response_env[:method])
      puts "DEBUG response status: " + response_env[:status].to_s if $CACHE_DEBUG

      last_modified = response_env[:response_headers]["Last-Modified"]

      # Generate key using header hash
      key = request_key

      # If the last retrieve time is less than expiry
      if response_env[:status] == 304 && cache_exist?(key)
        stored_obj = cache_read(key)

        # Update if last modified is different
        if stored_obj[:last_modified] != last_modified
          puts "UPDATING CACHE #{response_env[:url].to_s}" if $CACHE_DEBUG
          stored_obj[:last_modified] = last_modified
          cache_write(last_modified_key, last_modified)
          cache_write(key, stored_obj)
        end

        ld_obj = stored_obj[:ld_obj]
      else
        if response_env[:body].nil? || response_env[:body].empty?
          # We got here with an empty body, meaning the object wasn't
          # in the cache (weird). So re-do the request.
          puts "REDOING REQUEST NO CACHE ENTRY #{response_env[:url].to_s}"
          env[:request_headers].delete("If-Modified-Since")
          response_env = @app.call(env).env
        end
        ld_obj = LinkedData::Client::HTTP.object_from_json(response_env[:body])
        expiry = response_env[:response_headers]["Cache-Control"].to_s.split("max-age=").last.to_i
        if expiry > 0 && last_modified
          # This request is cacheable, store it
          puts "STORING OBJECT: #{response_env[:url].to_s}" if $CACHE_DEBUG
          stored_obj = {last_modified: last_modified, ld_obj: ld_obj}
          cache_write(last_modified_key, last_modified)
          cache_write(last_retrieved_key, true, expires_in: expiry)
          cache_write(key, stored_obj)
        end
      end

      response = ObjectCacheResponse.new(response_env)
      response.parsed_body = ld_obj
      return response
    end
  end
end