Class Rack::Cache::MetaStore
In: lib/rack/cache/metastore.rb
Parent: Object

The MetaStore is responsible for storing meta information about a request/response pair keyed by the request‘s URL.

The meta store keeps a list of request/response pairs for each canonical request URL. A request/response pair is a two element Array of the form:

  [request, response]

The request element is a Hash of Rack environment keys. Only protocol keys (i.e., those that start with "HTTP_") are stored. The response element is a Hash of cached HTTP response headers for the paired request.

The MetaStore class is abstract and should not be instanstiated directly. Concrete subclasses should implement the protected read, write, and purge methods. Care has been taken to keep these low-level methods dumb and straight-forward to implement.

Methods

cache_key   invalidate   lookup   purge   read   store   write  

Classes and Modules

Class Rack::Cache::MetaStore::Dalli
Class Rack::Cache::MetaStore::Disk
Class Rack::Cache::MetaStore::Heap
Class Rack::Cache::MetaStore::MemCacheBase
Class Rack::Cache::MetaStore::MemCached

Constants

HEAP = Heap
MEM = HEAP
DISK = Disk
FILE = Disk
MEMCACHE = if defined?(::Memcached)

Public Instance methods

Generate a cache key for the request.

[Source]

    # File lib/rack/cache/metastore.rb, line 84
84:     def cache_key(request)
85:       keygen = request.env['rack-cache.cache_key'] || Key
86:       keygen.call(request)
87:     end

Invalidate all cache entries that match the request.

[Source]

     # File lib/rack/cache/metastore.rb, line 90
 90:     def invalidate(request, entity_store)
 91:       modified = false
 92:       key = cache_key(request)
 93:       entries =
 94:         read(key).map do |req, res|
 95:           response = restore_response(res)
 96:           if response.fresh?
 97:             response.expire!
 98:             modified = true
 99:             [req, persist_response(response)]
100:           else
101:             [req, res]
102:           end
103:         end
104:       write key, entries if modified
105:     end

Locate a cached response for the request provided. Returns a Rack::Cache::Response object if the cache hits or nil if no cache entry was found.

[Source]

    # File lib/rack/cache/metastore.rb, line 28
28:     def lookup(request, entity_store)
29:       key = cache_key(request)
30:       entries = read(key)
31: 
32:       # bail out if we have nothing cached
33:       return nil if entries.empty?
34: 
35:       # find a cached entry that matches the request.
36:       env = request.env
37:       match = entries.detect{|req,res| requests_match?(res['Vary'], env, req)}
38:       return nil if match.nil?
39: 
40:       req, res = match
41:       if body = entity_store.open(res['X-Content-Digest'])
42:         restore_response(res, body)
43:       else
44:         # TODO the metastore referenced an entity that doesn't exist in
45:         # the entitystore. we definitely want to return nil but we should
46:         # also purge the entry from the meta-store when this is detected.
47:       end
48:     end

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.

[Source]

    # File lib/rack/cache/metastore.rb, line 53
53:     def store(request, response, entity_store)
54:       key = cache_key(request)
55:       stored_env = persist_request(request)
56: 
57:       # write the response body to the entity store if this is the
58:       # original response.
59:       if response.headers['X-Content-Digest'].nil?
60:         digest, size = entity_store.write(response.body)
61:         response.headers['X-Content-Digest'] = digest
62:         response.headers['Content-Length'] = size.to_s unless response.headers['Transfer-Encoding']
63:         response.body = entity_store.open(digest)
64:       end
65: 
66:       # read existing cache entries, remove non-varying, and add this one to
67:       # the list
68:       vary = response.vary
69:       entries =
70:         read(key).reject do |env,res|
71:           (vary == res['Vary']) &&
72:             requests_match?(vary, env, stored_env)
73:         end
74: 
75:       headers = persist_response(response)
76:       headers.delete 'Age'
77: 
78:       entries.unshift [stored_env, headers]
79:       write key, entries
80:       key
81:     end

Protected Instance methods

Remove all cached entries at the key specified. No error is raised when the key does not exist.

[Source]

     # File lib/rack/cache/metastore.rb, line 159
159:     def purge(key)
160:       raise NotImplemented
161:     end

Locate all cached request/response pairs that match the specified URL key. The result must be an Array of all cached request/response pairs. An empty Array must be returned if nothing is cached for the specified key.

[Source]

     # File lib/rack/cache/metastore.rb, line 146
146:     def read(key)
147:       raise NotImplemented
148:     end

Store an Array of request/response pairs for the given key. Concrete implementations should not attempt to filter or concatenate the list in any way.

[Source]

     # File lib/rack/cache/metastore.rb, line 153
153:     def write(key, negotiations)
154:       raise NotImplemented
155:     end

[Validate]