Action Cache plugin
This is a drop in replacement for the Rails Action Cache. When this plugin is installed, the new behavior will take effect without any further configuration.
All documentation for the Rails Action Cache is still relevant. Sweepers still work, all the fragment stores are supported.
See my blog at http://blog.craz8.com to find some interesting uses of the extended behavior provided by this plugin
Installation
script/plugin install http://craz8.com/svn/trunk/plugins/action_cacheFeatures
# Store response headers from the original request so they can be returned with cache hits. Cookie headers are removed, so only the original request will cause a cookie to be set. # 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) # Allow clients to provide their own implementation of the cache key for the actions, e.g.- application.rb
# Cache different pages for Admin and Users
def action_fragment_key(options)
url_for(options).split('://').last + "/#{admin? : 'admin' : 'user'}"
enddef my_action
@response.time_to_live = 10.minutes
...
end lighttpd.conf:
fastcgi.server = ( ".fcgi" =>
( "app" =>
( "min-procs" => 1,
"max-procs" => 1,
"allow-x-send-file" => "enable",
"socket" => "/tmp/app.fcgi.socket",
"bin-path" => "/path/to/app/public/dispatch.fcgi",
"bin-environment" => ( "RAILS_ENV" => "development", "ENABLE_X_SENDFILE" => "true" )
)
)
) environment.rb:
ActionController::Base.fragment_cache_store = :file_store, "/path/to/cache/directory"
class ApplicationController < ActionController::Base
...
def cache_action?(action_name)
!admin?
end
...
end location /cache/ {
internal;
root /path/to/rails/app/current/tmp;
} nginx.conf:
location /cache/ {
internal;
root /path/to/rails/app/current/tmp;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header "ENABLE_X_ACCEL_REDIRECT" "true";
...
}
# environment.rb:
ActionController::Base.fragment_cache_store = :file_store, "/path/to/cache/directory" # Expires all formats of the action
expire_action :controller => 'foo', :action => 'bar'Performance
If a client requests an action whose output hasn’t changed since their last request, the returning of a 304 response instead of the full response greatly reduces the load on the server.
In my informal testing, with the X-Sendfile enabled, I was able to get about 20% more requests out of my rails application, based on the requests-per-second displayed in the rails log. This doesn’t mean the request is faster, but that the work of delivering the content is offloaded to the web server from the Rails app.
Contributors: Tom Fakes (tom@craz8.com) – Initial implementation, plugin implementation, x-sendfile work Scott Laird – Ideas for the timed expiry and programmable fragment_key features