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 #3 AssetTagHelper should accept a slightly wider range of protocols.
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.