rtomayko/rack-cache — Issue #42: MetaStore#store erases a valid response body if EntityStore#write and #open fail
Author: davisre
Created: 2011-11-11 22:10:36+00:00
State: open

I noticed that I get server failures when my EntityStore is unable or unwilling to save a response. Two examples: if memcache goes down, any writes through Dalli will fail and any reads will return nil. Or when I'm using a simple NilStore for testing in Rails, my writes will always do nothing and reads will always return nil (which can be useful for exercising an app's cache code without firing up an instance of memcached).

In both cases, Rack::Cache gets a valid response from Rails but then replaces the body with nil. This happens because MetaStore#store writes the response's body to the entity store (which fails), immediately reads it back from the store (getting nil), and then replaces the response's body with that nil.

Is there any reason for the metastore to replace the response body? Deleting the `entity_store.open` line from `MetaStore#store` would fix the two cases I'm having trouble with. That is, the server would still return a response, even if that response can't be cached. This would also eliminate an unnecessary read and get rid of the minute possibility that even a working store could throw away the entry between the write and subsequent read. But maybe I'm overlooking something? Does reading the newly stored body have some beneficial side-effect?

Here's the relevant section in 1.0.3 (and it looks similar in 1.1):

# write the response body to the entity store if this is the
# original response.
if response.headers['X-Content-Digest'].nil?
if request.env['rack-cache.use_native_ttl'] && response.fresh?
digest, size = entity_store.write(response.body, response.ttl)
else
digest, size = entity_store.write(response.body)
end
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

Thoughts?