-
Notifications
You must be signed in to change notification settings - Fork 22k
Description
This bug causes cached asset responses to be invalid after two successful requests. This means that with ActionController caching enabled in production, assets will not be returned correctly to clients. To us, this seems to be an RC-stopping issue.
In the Rails 3.1.0.beta1, using:
- rails (3.1.0.beta1)
- rack (1.3.0.beta)
- rack-cache (1.0.1)
There is a reproducible bug when ActionController caching is enabled (in production), where ActionDispatch::RailsMetaStore
, along with ActiveSupport::Cache::MemoryStore
, will ultimately cause Rack::Cache
to return an HTTP 0
(invalid!) response to Rack.
The implementation of Rack::Cache works by storing hashes into the cache to retrieve on future requests. Those hashes are written and pulled as necessary for invalidation.
The basic lifecycle looks like this:
- First request, cache empty, find file, generate fingerprint, append to file name, store request response hash information to cache, serve content back to client with a miss, store header response on the cache,
- Second request, identify matching file request based on name and fingerprint, read from cache, read and drop the
X-Status
header from the cached hash and return that hash forward to Rack. - Third request, identify matching file request based on name and fingerprint, read from cache, read and drop the
X-Status
header (except it's already been DELETED!), find no status, return HTTP 0 to rack. - All subsequent matches follow Status: 500 Internal Server Error private method `split' called for Mime::Type in #3.
So, it seems to be that because the MemoryStore cache is handing back the hash object directly, Rack::Cache is then manipulating it before handing it upstream to Rack. In most cases, that's fine, except that because MemoryStore is handing back the actual object, and Rack::Cache is manipulating it, the cache object is ultimately, unknowingly being manipulated. So, subsequent finds are returning the "bad" object.