Class: Rack::Client::Cache::MetaStore
- Inherits:
-
Object
- Object
- Rack::Client::Cache::MetaStore
- Defined in:
- lib/rack/client/middleware/cache/metastore.rb
Direct Known Subclasses
Defined Under Namespace
Classes: Heap
Constant Summary collapse
Instance Method Summary collapse
- #cache_key(request) ⇒ Object
- #lookup(request, entity_store) ⇒ Object
-
#persist_request(request) ⇒ Object
Extract the environment Hash from
request
while making any necessary modifications in preparation for persistence. - #persist_response(response) ⇒ Object
-
#requests_match?(vary, env1, env2) ⇒ Boolean
Determine whether the two environment hashes are non-varying based on the vary response header value provided.
-
#restore_response(hash, body = nil) ⇒ Object
Converts a stored response hash into a Response object.
-
#store(request, response, entity_store) ⇒ Object
Write a cache entry to the store under the given key.
Instance Method Details
#cache_key(request) ⇒ Object
61 62 63 64 |
# File 'lib/rack/client/middleware/cache/metastore.rb', line 61 def cache_key(request) keygen = request.env['rack-client-cache.cache_key'] || Key keygen.call(request) end |
#lookup(request, entity_store) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/rack/client/middleware/cache/metastore.rb', line 6 def lookup(request, entity_store) key = cache_key(request) entries = read(key) # bail out if we have nothing cached return nil if entries.empty? # find a cached entry that matches the request. env = request.env match = entries.detect{|req,res| requests_match?(res['Vary'], env, req)} return nil if match.nil? req, res = match if body = entity_store.open(res['X-Content-Digest']) restore_response(res, body) else # TODO the metastore referenced an entity that doesn't exist in # the entitystore. we definitely want to return nil but we should # also purge the entry from the meta-store when this is detected. end end |
#persist_request(request) ⇒ Object
Extract the environment Hash from request
while making any necessary modifications in preparation for persistence. The Hash returned must be marshalable.
69 70 71 72 73 |
# File 'lib/rack/client/middleware/cache/metastore.rb', line 69 def persist_request(request) env = request.env.dup env.reject! { |key,val| key =~ /[^0-9A-Z_]/ } env end |
#persist_response(response) ⇒ Object
75 76 77 78 79 |
# File 'lib/rack/client/middleware/cache/metastore.rb', line 75 def persist_response(response) hash = response.headers.to_hash hash['X-Status'] = response.status.to_s hash end |
#requests_match?(vary, env1, env2) ⇒ Boolean
Determine whether the two environment hashes are non-varying based on the vary response header value provided.
90 91 92 93 94 95 96 |
# File 'lib/rack/client/middleware/cache/metastore.rb', line 90 def requests_match?(vary, env1, env2) return true if vary.nil? || vary == '' vary.split(/[\s,]+/).all? do |header| key = "HTTP_#{header.upcase.tr('-', '_')}" env1[key] == env2[key] end end |
#restore_response(hash, body = nil) ⇒ Object
Converts a stored response hash into a Response object. The caller is responsible for loading and passing the body if needed.
83 84 85 86 |
# File 'lib/rack/client/middleware/cache/metastore.rb', line 83 def restore_response(hash, body=nil) status = hash.delete('X-Status').to_i Rack::Client::Cache::Response.new(status, hash, body) end |
#store(request, response, entity_store) ⇒ Object
Write a cache entry to the store under the given key. Existing entries are read and any that match the response are removed. This method calls #write with the new list of cache entries.
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 |
# File 'lib/rack/client/middleware/cache/metastore.rb', line 31 def store(request, response, entity_store) key = cache_key(request) stored_env = persist_request(request) # write the response body to the entity store if this is the # original response. if response.headers['X-Content-Digest'].nil? digest, size = entity_store.write(response.body) response.headers['X-Content-Digest'] = digest response.headers['Content-Length'] = size.to_s unless response.headers['Transfer-Encoding'] response.body = entity_store.open(digest) end # read existing cache entries, remove non-varying, and add this one to # the list vary = response.vary entries = read(key).reject do |env,res| (vary == res['Vary']) && requests_match?(vary, env, stored_env) end headers = persist_response(response) headers.delete 'Age' entries.unshift [stored_env, headers] write key, entries key end |