How to setup and use Rack::Cache with Rails 2.3

Ruby posted about 1 year ago by christian

First install rack-cache:

   1  sudo gem install rack-cache

Install Rails version 2.3 or greater:

   1  sudo gem install rails

Or, freeze your project to Rails edge:

   1  cd project
   2  rake rails:freeze:edge

Add this to config/environment.rb:

   1  config.middleware.use Rack::Cache,
   2    :verbose => true,
   3    :metastore   => 'file:/var/cache/rack/meta',
   4    :entitystore => 'file:/var/cache/rack/body'

Note the name is middleware, not middlewares which is used in all examples I found online, even the Rails blog.

Check the Rack configuration:

   1  rake middleware

You should see something like this:

   1  use Rack::Lock
   2  use ActionController::Failsafe
   3  use ActionController::Reloader
   4  use ActionController::Session::CookieStore, #<Proc:0x00002b45ab39e3a8@(eval):8>
   5  use ActionController::RewindableInput
   6  use ActionController::ParamsParser
   7  use Rack::MethodOverride
   8  use Rack::Head
   9  use Rack::Cache, {:metastore=>"file:/var/cache/rack/meta", :entitystore=>"file:/var/cache/rack/body", :verbose=>true}
  10  use ActiveRecord::QueryCache
  11  run ActionController::Dispatcher.new

Tell Rack to cache data by putting this in your controller:

   1  expires_in 5.minutes, :public => true

Note that you should avoid caching private data when the user is signed in. In this case you should set the Cache-Control header to private or completely avoid using expires_in:

   1  expires_in 5.minutes, :public => true if !signed_in?

Rails sets cache-control to private by default, Rack needs public content.

With verbose set to true, you’ll see this in the thin logs:

   1  [cache] trace: cache miss
   2  [cache] trace: fetching response from backend
   3  [cache] trace: store backend response in cache (ttl: 300s)
   4  [cache] trace: storing response in cache
   5  [cache] trace: delivering response ...
   6  [cache] trace: cache hit (ttl: 276s)
   7  [cache] trace: delivering response ...

Note that ActionController::AbstractRequest has been renamed to ActionController::Request in Rails 2.3.0, so some plugins might throw this error in your face:

   1  load_missing_constant': uninitialized constant ActionController::AbstractRequest

Problems

If you get one of these errors you need to change the way you require the rack-cache gem:

   1  uninitialized constant Rack::Cache
   2  
   3  uninitialized constant Rails::Rack::Cache

I’ve found that this doesn’t work:

   1  config.gem "rack/cache", :lib => 'rack/cache'

Instead, I’m requiring rack-cache by adding this to environment.rb:

   1  require 'rack-cache'
   2  
   3  
   4  Rails::Initializer.run do |config|

References

HTTP RFC – Cache-Control
Rack::Cache options documentation
Rails expires_in documentation

Tagged rack, rack::cache, cache, rails, 2.3