Contact Me
Rails Recipes
My Job Went to India

One of the first thing you learn when you write your own weblog software and get a decent number of subscribers, is that you need to provide a way for aggregators to tell you which version of a feed they have, so your server can respond by telling the aggregator that it already has the latest version. Otherwise, you waste a lot of bandwidth sending the same polling client the same data over and over again.

This is commonly handled in the weblog software world with a combination of the ETag header, which allows clients and servers to communicate in terms of a variant of a specific resource and the “304 Not Modified” HTTP response and an empty response body.

This technique isn’t limited in usefulness to RSS and Atom feeds. You could use the same thing with HTML, PDF, anything you like. If the client sends you an ETag and it matches the version you already have, you give it a 304 with an empty response body.

It turns out that if you use a Web framework with a consistent rendering system, you can bake this kind of behavior right into the framework.

A few hours ago, David Heinemeier Hansson did just that.

“Cool, how do I use it?”

If you’re using Edge Rails, it just happens automatically.

Who knows if this will still be there in a month, but it’s at worst a cool experiment and at best a nice optimization for all future Rails applications.

UPDATE: Rick Olson just pointed out to me that a weblog is not a good Rails-specific example of when this new feature would be useful, since weblogs can usually be cached at the page level (after which real Web servers can just do their thing with the static content). He is, of course, right. I didn’t mean for the weblog example to carry through into what you would use this feature for. It would be very useful for situations where content is dynamically generated on, say, a per-user or per-account basis—-like most of the applications most of us make with Rails.

6 Comments

  1. Frugel Says:

    On Rick’s observation: what you’re saying is that when a page is dynamically created at two times x and y, rails will know if the page versions x and y will be the same or different and therefore will send the appropriate HTTP response as if it were a previously existing static file?

    Just trying to get my head around this. I’m no rails expert, but i can’t think of a time where “content is dynamically generated on, say, a per-user or per-account basis” could not be cached as a static file?

  2. Dominic Mitchell Says:

    This is a good start, but the etag calculation needs to be overrideable on a per-action basis. One of the main things about etags is that it’s meant to be cheaper than caclulating the full resource that you’re trying to retrieve. So, DHH’s patch saves bandwidth (a noble goal), but still does all the work on your server. That’s OK, but it’d be real good to come up with an override so you can calculate etags in a slightly better fashion.

  3. Thijs van der Vossen Says:

    Dominic, there’s a patch that allows you to set your own Etag header before you call render at http://dev.rubyonrails.org/ticket/7580

  4. Chad Fowler Says:

    Frugel,

    The reason you can’t cache per-user content (or per-account) as a static file is that the content would then be unprotected and web-accessible. You could, for example, randomly auto-increment IDs on the URL to get other people’s cached content without having to authenticate.

  5. DHH Says:

    Thanks, Thijs. Committed. If you want to manage your own etagging, knock yourself out!

  6. Thijs van der Vossen Says:

    David, thanks for the quick commit.

Sorry, comments are closed for this article.