Ruby Sinatra中的缓存变量

Ruby Sinatra中的缓存变量,ruby,caching,redis,sinatra,Ruby,Caching,Redis,Sinatra,我有一个由约60个排序集组成的集合,每个集合包含约200个成员,我正在尝试处理这些成员。以前我构建了一个Redis(Lua)服务器端脚本,但是请求的大(O)时间值在负载下停滞了 我现在正试图将处理过程转移到Ruby/Sinatra上,并刷新每一个被证明效率低下的请求的结果。根据下面的代码,有没有办法在Sinatra中缓存“分数”结果,这样我就不必在每次请求时都从Redis中提取分数 global = redis.smembers("id_list") i=0 scores = redis.pi

我有一个由约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

Sinatra有一个全局作用域,其中对象将在请求之间持久化。如果您定义了一个scorekeeper类,该类为您的分数维护一个实例变量,那么您可以拥有一个保存该值的分数查找方法。例如:

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

这样,在第一个请求中,scores属性将被填充,在所有后续请求中,它将使用缓存的值。

这似乎不会缓存结果。我已经将上述内容输入到我的代码中,并且我的日志显示,每次收到请求时,我都会给Redis打电话。你是在shotgun下运行Sinatra还是在每次请求之前重新加载你的应用程序?我刚刚用上面的代码做了一个测试,将redis调用替换为puts,它只在第一次请求/scores时调用get_scores函数