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.
Classes and Modules
Class Rack::Cache::MetaStore::DalliClass 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.
# File lib/rack/cache/metastore.rb, line 83 83: def cache_key(request) 84: keygen = request.env['rack-cache.cache_key'] || Key 85: keygen.call(request) 86: end
Invalidate all cache entries that match the request.
# File lib/rack/cache/metastore.rb, line 89 89: def invalidate(request, entity_store) 90: modified = false 91: key = cache_key(request) 92: entries = 93: read(key).map do |req, res| 94: response = restore_response(res) 95: if response.fresh? 96: response.expire! 97: modified = true 98: [req, persist_response(response)] 99: else 100: [req, res] 101: end 102: end 103: write key, entries if modified 104: 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.
# File lib/rack/cache/metastore.rb, line 27 27: def lookup(request, entity_store) 28: key = cache_key(request) 29: entries = read(key) 30: 31: # bail out if we have nothing cached 32: return nil if entries.empty? 33: 34: # find a cached entry that matches the request. 35: env = request.env 36: match = entries.detect{|req,res| requests_match?(res['Vary'], env, req)} 37: return nil if match.nil? 38: 39: req, res = match 40: if body = entity_store.open(res['X-Content-Digest']) 41: restore_response(res, body) 42: else 43: # TODO the metastore referenced an entity that doesn't exist in 44: # the entitystore. we definitely want to return nil but we should 45: # also purge the entry from the meta-store when this is detected. 46: end 47: 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.
# File lib/rack/cache/metastore.rb, line 52 52: def store(request, response, entity_store) 53: key = cache_key(request) 54: stored_env = persist_request(request) 55: 56: # write the response body to the entity store if this is the 57: # original response. 58: if response.headers['X-Content-Digest'].nil? 59: digest, size = entity_store.write(response.body) 60: response.headers['X-Content-Digest'] = digest 61: response.headers['Content-Length'] = size.to_s unless response.headers['Transfer-Encoding'] 62: response.body = entity_store.open(digest) 63: end 64: 65: # read existing cache entries, remove non-varying, and add this one to 66: # the list 67: vary = response.vary 68: entries = 69: read(key).reject do |env,res| 70: (vary == res['Vary']) && 71: requests_match?(vary, env, stored_env) 72: end 73: 74: headers = persist_response(response) 75: headers.delete 'Age' 76: 77: entries.unshift [stored_env, headers] 78: write key, entries 79: key 80: end
Protected instance methods
Remove all cached entries at the key specified. No error is raised when the key does not exist.
# File lib/rack/cache/metastore.rb, line 158 158: def purge(key) 159: raise NotImplemented 160: 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.
# File lib/rack/cache/metastore.rb, line 145 145: def read(key) 146: raise NotImplemented 147: 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.
# File lib/rack/cache/metastore.rb, line 152 152: def write(key, negotiations) 153: raise NotImplemented 154: end