在Rails中预编译/预加载缓存的片段

时间:2012-10-04 11:57:48

标签: ruby-on-rails caching

使用Rails 3.1.1和Herkou

我的应用中有1.000个产品。它们都有一个非常慢的控制器,它可以通过片段缓存有效地解决。虽然数据不会经常变化,但它仍然需要定期到期(我会通过扫描),在我的情况下每周一次。

现在,在扫描缓存的视图后,我不希望我的用户通过尝试一个接一个地访问产品来创建新的片段(在第一次加载时大约需要6-8秒,对于缓存需要2-3秒加载)。我假设我可以使用某种脚本逐个加载每个产品页面,从而使服务器创建这些片段。

我可以想象这可以用三种方式处理:

  1. 在我的本地计算机上运行一个脚本,尝试使用某种get-command访问每个url - 下行:不太漂亮,会以我不喜欢的方式影响访问者统计数据。

  2. 在清扫器之后在服务器上运行相同类型的脚本,这将加载每个产品。在那种情况下我该怎么做?

  3. 使用智能Rails命令自动执行此操作。有这么优雅的命令吗?

2 个答案:

答案 0 :(得分:0)

我制作了这个脚本并且它有效。 “product.slug”是因为我安装了friendly_id。它将生成名称为www.mydomain.com/productabc-123/的url变量,这些变量将由Nokogiri读取(此解决方案需要Nokogiri gem)。

请注意我从片段缓存切换到此解决方案中的操作缓存(与我使用片段缓存的问题相反)。这个的重要区别是当我检查缓存if Rails.cache.exist?('views/www.mydomain.com/' + product.slug)时。对于fragment_caching,它应该是片段名称。

require 'nokogiri'
require 'open-uri'

Product.all.each do |product|
  url = 'http://www.mydomain.com/' + product.slug  
  begin      
    if Rails.cache.exist?('views/www.mydomain.com/' + product.slug)     
      puts url + " is already in cache"
    else
      doc = Nokogiri::HTML(open(url))
      puts "Reads " + url
# Verifies if the caching worked. Only for trouble shooting
      if Rails.cache.exist?('views/www.mydomain.com/' + product.slug)     
        puts "--->" + url + " is NOW in the cache"
      else
        puts "--->" + url + " is still not in the cache!"
      end
      sleep 1
    end
  rescue
    puts 'Normal rescue of ' + url
  rescue Timeout::Error
    puts 'Timeout rescue of ' + url
    puts 'Sleep for 5 sec'
    sleep 5
    retry
  end
end

答案 1 :(得分:0)

创建一个运行为rake任务的脚本,或者更好的是一个运行和卷曲页面的worker。只要你可以调用curl

就不需要包含gem
`curl -A "CacheRefresher" #{ENV['HOSTNAME']}/api/v1/#{klass.name.underscore.pluralize}/#{id} >/dev/null 2>&1`