Finally found a question and answer:
Q: "Warm Up Cache" on deployment
A: https://stackoverflow.com/a/942774/593053
Leaving my question here so that others can follow the trail and learn
from my pain.
Also relevant: Rails 3.2: Pre-render (bake) a new page cache immediately after expiry?
My full solution was to adopt the convention that if cache=regen
is in a requested URL, that means that the generated page should be stuffed into the cache.
For controllers for which I want caching, include CacheRegen
. CacheRegen
causes the controller to not read from cache when cache=regen, and to not put cache=regen into the key when storing in the cache.
The code for which is:
module CacheRegen
def read_fragment(key, options = nil)
if /cache=regen/.match(key)
logger.info("forcing cache miss due to param cache=regen, key=#{key}")
return nil
end
super(key, options)
end
def write_fragment(key, content, options = nil)
unless key.sub!(/cache=regen/, '').nil?
key.sub!(/\?\&/, '?')
key.sub!(/\&\&/, '&')
key.sub!(/\?$/, '')
key.sub!(/\&$/, '')
logger.info("wrote page to cache with key #{key}")
end
super(key, content, options)
end
end
Finally, I put the following code in new_pages.rake:
require 'action_dispatch'
def get_url(sess, url)
uri = "http://YOURSITE.com/" + url + "cache=regen"
puts "retrieving " + uri
foo = sess.get(uri)
puts "got it. #{foo}, #{sess.response.body.length} bytes"
end
desc "If necessary, generate new versions of the most expensive pages"
task :new_pages => :environment do
puts "Updating pages..."
sess = ActionDispatch::Integration::Session.new(Rails.application)
["controller1", "controller2", "controller3"].each { |noun|
get_url(sess, noun + "?")
}
puts "done."
end
And in my environment, I have a deploy
task which depends on the new_pages
task.
Is there some gem out there that makes all this more automagical?