使用expired_after like功能在ruby中使用实例变量进行缓存

时间:2012-02-07 03:53:37

标签: ruby-on-rails ruby caching

我正在开发一个ruby应用程序(不是rails),我正在寻找一种非常简单的方法来缓存一些常用的结果。例如:

 @users ||= User.all

现在这种方法很完美,但我正在寻找一种方法来添加像 expire 这样的选项,它会在每个时间段刷新命令。换句话说,我需要在每个时间片段中或多次后执行相同的操作。我记得在rails中我曾经运行memcached并使用类似:expire或:expired_at。

任何帮助都将受到高度赞赏。

2 个答案:

答案 0 :(得分:1)

如下:

class Class
  # create a method whose return value will be cached for "cache_for" seconds
  def cached_method(method,cache_for,&body)
    define_method("__#{method}__".to_sym) do |*a,&b|
      body.call(*a,&b)
    end
    class_eval(<<METHOD)
      def #{method}(*a,&b)
        unless @#{method}_cache && (@#{method}_expiry > Time.now)
          @#{method}_cache  = __#{method}__(*a,&b)
          @#{method}_expiry = Time.now + #{cache_for}
        end
        @#{method}_cache
      end
METHOD
  end
end

您可以像以下一样使用它:

class MyClass
  cached_method(:users,60) do
    User.all
  end
end

这会将用户缓存60秒。如果在经过60秒或更长时间后再次在同一个对象上调用users,它将再次执行方法体并更新缓存。

答案 1 :(得分:1)

你不觉得上面的那个有点复杂吗?

我正在尝试类似的事情:

Cache ={}
def fetch(key, ttl)
  obj, timestamp = Cache[key.to_sym]
  if obj.nil? || Time.now - timestamp > ttl
    obj = yield
    Cache[key]=[obj, now]
  end 
  obj
end

我很想听听你对这个的评论