以正确的方式实现缓存

时间:2012-08-17 06:50:18

标签: ruby-on-rails ruby ruby-on-rails-3 caching

我是Ruby on Rails的新手(几天前刚刚开始使用它)。我正在制作一个简单的Web前端来显示各种系统信息,包括S.M.A.R.T信息。我做了这个小班:

class SmartValues
    attr_reader :data
    KEYS  = [:id, :name, :flag, :value, :worst, :thresh, :type, :updated, :failed, :raw]

    def initialize(devices)
            @data = Hash[devices.map {|dev| [dev, SmartValues.getValues(dev)]}]
    end

    def self.getValues(device)
            lines = `sudo /usr/sbin/smartctl -A #{device}`.split("\n")[7..-1].collect! { |line| line.split }
            return lines.map { |line| Hash[KEYS.zip line] }
    end
end

它工作正常,除了它包含在我的控制器中,如下所示:

class HomeController < ApplicationController
    def index
        @smart = SmartValues.new(["/dev/sda", "/dev/sdb", "/dev/sdc", "/dev/sdd", "/dev/sde", "/dev/sdf"]).data
    end
end

因此,对于页面的每个请求,必须多次执行 smartctl 二进制文件。我想添加某种缓存,以便定期更新信息,但不是每次请求都更新。什么是正确的RoR-ish方式?

1 个答案:

答案 0 :(得分:3)

def self.lines(device)
  Rails.cache.fetch("#{device}_lines", :namespace => "smart_values", :expires_in => 15.minutes) do
    `sudo /usr/sbin/smartctl -A #{device}`.split("\n")[7..-1].collect! { |line| line.split }
  end
end

def self.getValues(device)
  lines(device).map { |line| Hash[KEYS.zip line] }
end