codahale.com٭blog

This is my old blog. My current writing is here: codahale.com

Rails Plugin: http_caching

Allows your Rails application to take advantage of the caching mechanisms built into HTTP 1.1 (i.e., 304 Not Modified return code). Inspired by a Rails cookbook entry (manuals.rubyonrails.com/read/chapter/62). If it fits into your app’s architecture, HTTP caching can make a real difference in user-perceived speed. “And it must pop pop pop!”

Installation

If your project is source-controlled by Subversion (which it should be, really), the easiest way to install this is via Rails’ plugin script:

./script/plugin install -x http://svn.codahale.com/http_caching

If you’re not using Subversion, or if you don’t want it adding svn:externals in your project, remove the -x switch:

./script/plugin install http://svn.codahale.com/http_caching

Usage

An example using send_data:

  def get_orders
    @photo = Photo.find(params[:id])
    unless_cached_after @photo.updated_at do
      send_data @photo.data, :type => @photo.mime_type, :disposition => 'inline'
    end
  end

If the photo hasn’t been updated since the last time the client requested it, the photo isn’t sent, saving you time and bandwidth.

Another example, this time using a simple RHTML view:

  def get_user_profile
    @user = User.find(params[:id])
    render_unless_cached_after @user.updated_at
  end

A slightly more complicated RHTML example:

  def get_orders
    render_unless_cached_after Order.maximum(:updated_at), :layout => 'orders_feed', :action => 'all_orders'
  end

Or you can keep frequent refreshers from swamping your server:

  def shiny_object
    unless_cached_after 10.minutes.ago do
      @shiny_object = ShinyObject.complicated_database_call(:woo => :hah)
    end
  end

You get the idea.

(And yes, all I do is make Rails plugins.)

3 Responses to “Rails Plugin: http_caching”

  1. RosSoft » Http Cache Component (updated) Says:

    [...] Copy to /app/controllers/components/http_cache.php <?php /**  * Http Cache Component  * Uses built in HTTP 1.1 caching mechanism  * (304 Not Modified)  *   * @author RosSoft  * @license MIT  * @version 0.2  *  * @link http://blog.codahale.com/2006/05/23/rails-plugin-http_caching/  *  *  * Example 1:  * $this->httpCache->cache($timestamp_modified_record);  * $timestamp_modified_record is the timestamp of the content (like 'modified' field)  *  * Example 2:  * $this->httpCache->expires('+1 Day');  * The page will be cached until expire time.  *  * (cache and expires are incompatible, use one of them for each different url)  */ [...]

  2. Jim Kane Says:

    Nice work! I’m already doing some page and fragment caching in my app — do you see this as a straight replacement for those, or do you nest them like
    unless_cached_after blah do
    unless read_fragment :action => :foo, :id => bar.id, :part => ‘feh’
    end
    end

    that starts to look a little gnarly.

  3. Coda Says:

    Jim–You should use them both. HTTP caching will help improve response times (when the data is cachable) when the client already has a fresh copy of the data. Page/action/fragment caching helps improve response times when the server has a fresh copy of the data in the cache.

    And yes, it does start to get gnarly. I wish that weren’t the case, but it is.