2013-11-15 2 views
1

나는 처리하려고하는 ~ 200 명의 구성원이 들어있는 ~ 60 개의 정렬 된 집합을 가지고 있습니다. 이전에는 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를 산탄 총이나 앱을 다시로드하는 프로그램으로 실행하고 있습니까? 방금 위 코드를 사용하여 테스트를 수행하고 redis 호출을 puts로 바꾸고 첫 번째 요청의 get_scores 함수를/score – mattwise