Question

Using Rails 3.2 in development mode, I'm trying to test out some simple page caching.

pages_controller.rb

class PagesController < ActionController::Base

  caches_page :index, :show

  def index
    @pages = Page.all
  end

  def show
    @page = Page.find(params[:id])
  end

end

development.rb

config.action_controller.perform_caching = true

application.rb

config.action_controller.page_cache_directory = File.join(Rails.root, 'public')

When I test this setup out, it seems to process these actions like normal, and the page cache gets written as expected. However, subsequent requests report the following two things that have me confused:

  1. It seems to miss the cache, but...
  2. Requests afterwards don't seem to load the controller, run any queries, etc., leading me to believe that it DID load from the cache.

Here's what the log outputs on first request, and then five reloads afterwards:

Started GET "/pages" for 127.0.0.1 at 2012-02-12 21:01:24 -1000
Processing by PagesController#index as HTML
  Page Load (0.2ms)  SELECT `pages`.* FROM `pages` 
  Rendered pages/index.html.erb (0.8ms)
Write page /Users/ckihe/Sites/experiment/public/pages.html (0.3ms)
Completed 200 OK in 3ms (Views: 1.9ms | ActiveRecord: 0.2ms)
cache: [GET /pages] miss
cache: [GET /pages] miss
cache: [GET /pages] miss
cache: [GET /pages] miss
cache: [GET /pages] miss

Anyone have any ideas why the cache says it's missing?

Was it helpful?

Solution

There are multiple ways in which caching can happen (and yes there is some redundancy).

Starting with (I think) rails 3.1, Rack::Cache is setup for you. This is an http level cache that understands all about expiry times, etags etc and can store the data in a variety of cache stores. This is what is reporting a cache miss, probably because you're not emitting the cache control headers that would allow it to cache the page (see the expires_in or fresh_when helpers).

Page caching of the sort you have configured is way older and operates entirely dIfferently. It dumps the rendered HTML into the directory of your choice and rails is then serving those as static assets (in production you would configure this to be served straight from the web server without touching ruby level code). This caching is less smart and knows nothing about http cache control headers and so on (but is on the other hand very fast).

So in summary you've got two caching schemes in place that are unaware of each other which is why you get a miss from one of them and a hit from the other one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top