终于找到一个问答:
问:"Warm Up Cache" on deployment
答:https://stackoverflow.com/a/942774/593053
将我的问题留在这里,以便其他人可以跟踪并学习
从我的痛苦中。
也相关:Rails 3.2: Pre-render (bake) a new page cache immediately after expiry?
我的完整解决方案是采用约定,如果cache=regen 在请求的 URL 中,这意味着生成的页面应该被填充到缓存中。
对于我想要缓存的控制器,include CacheRegen。 CacheRegen 导致控制器在 cache=regen 时不从缓存中读取,并且在缓存中存储时不将 cache=regen 放入 key。
代码如下:
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
最后,我在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
在我的环境中,我有一个 deploy 任务,它依赖于 new_pages 任务。
有没有什么宝石可以让这一切变得更加自动化?