2013-11-15 35 views
1

我有一套約60個有序集合,每個集合包含約200個成員,我正在嘗試處理。之前,我構建了一個Redis(Lua)服務器端腳本,但請求的大(O)時間值在負載下緩慢下降。緩存變量在Sinatra

我現在正在嘗試將處理任務卸載到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 

回答

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 

現在你的末日應用只需實例化任何資源聲明之外的記分員:

require 'sinatra' 
keeper = Scorekeeper.new 

get '/scores' do 
    keeper.scores 
end 

這樣在第一次請求,分數屬性將得到填充,所有進一步請求,它將使用緩存的值。

+0

這似乎沒有緩存結果。我已經將上面的代碼放入我的代碼中,並且我的日誌記錄顯示每次有請求進入時,我仍然會打電話給Redis。 – tjrburgess

+0

您是在霰彈槍下運行Sinatra還是在每次請求之前重新加載您的應用程序?我只是用上面的代碼做了一個測試,用put代替redis調用,並且它只在第一次請求/ get時調用get_scores函數 – mattwise