Sinatra中的缓存变量

时间:2013-11-15 12:53:54

标签: ruby caching redis sinatra

我有一组约60个有序的集合,每个集合包含约200个我正在尝试处理的成员。以前我构建了一个Redis(Lua)服务器端脚本,但请求的大(O)时间值在负载下陷入困境。

我现在正在尝试将处理卸载到Ruby / Sinatra,并在每个请求中刷新结果,证明效率低下。鉴于下面的代码,有没有办法在Sinatra中缓存“得分”结果,所以我不必在每次请求时都从Redis中提取?

global = redis.smembers("id_list")

i=0
scores = redis.pipelined do
  global.each do |key|
    redis.zrange("user:#{global[i]}",0,100,:with_scores => true)
    i+=1
  end
end

1 个答案:

答案 0 :(得分:3)

Sinatra具有全局范围,其中对象将在请求之间保持不变。如果您定义了一个记分员类来维护您的分数的实例变量,那么您可以使用包含该值的分数的查找方法。例如:

class Scorekeeper
  def initialize
    @scores = nil
  end

  def scores
    @scores ||= get_scores
  end

  def get_scores
    global = redis.smembers("id_list")
    i=0
    scores = redis.pipelined do
      global.each do |key|
        redis.zrange("user:#{global[i]}",0,100,:with_scores => true)
        i+=1
      end
    end
    scores
  end
end

现在你的Sinatra应用程序只需要在任何资源声明之外实例化一个记分员:

require 'sinatra'
keeper = Scorekeeper.new

get '/scores' do
  keeper.scores
end

这种方式在第一次请求时,将填充score属性,在所有进一步的请求中,它将使用缓存的值。