Due to issues with page caching, I just started looking at the Rails action cache. There are a few things that could be done better by the built in code, but since this is written in Ruby, I can make those changes in my code and override the pieces I want.
The core of Rails Action Caching is the around filter applied to all actions that are to be cached. I re-implemented the before and after methods to make the changes I needed.
Here are the things I changed:
- Store cache entries as YAML streams so the Response headers from the original response can be returned with cache hits
- Add a ‘last-modified’ header to the response to get the client to use a get-if-modified request
- If the client has the response we have cached, don’t send it again, send a ‘304 Not Modified’ response to reduce data on the wire
- Fix a bug in the original Rails code where responses other than ‘200 OK’ are cached (since the headers aren’t cached in the original, all the clients would get is an empty ‘200 OK’ response from subsequent requests). Patch submitted
The code can be downloaded here. Place action-cache.rb in your lib directory and require ‘action-cache’ in your environment.rb to hook this in. Since this extends Rails Action Caching, all the documentation for that code still applies, e.g.
The OutputCompression filter works with this code if it is set to run before the action cache. If you put the OutputCompression filter in your Application.rb file, and the action caching in specific controllers, both will work correctly.
Update: It looks like IE doesn’t send the If-Modified header unless the response contained a Cache-Control header. The code will now set the Cache-Control to max-age=1 if the action did not set it.