2012-04-24 70 views
1

我正在使用合適的Redis EM gem(我的案例中的'em-hiredis')讀取在EventMachine反應器循環中設置的Redis,並且必須檢查某些Redis集合是否包含級聯中的成員。我的目的是讓集的名稱是不是空:Ruby EventMachine&functions

require 'eventmachine' 
require 'em-hiredis' 

def fetch_queue 
    @redis.scard('todo').callback do |scard_todo| 
    if scard_todo.zero? 
     @redis.scard('failed_1').callback do |scard_failed_1| 
     if scard_failed_1.zero? 
      @redis.scard('failed_2').callback do |scard_failed_2| 
      if scard_failed_2.zero? 
       @redis.scard('failed_3').callback do |scard_failed_3| 
       if scard_failed_3.zero? 
        EM.stop 
       else 
        queue = 'failed_3' 
       end 
       end 
      else 
       queue = 'failed_2' 
      end 
      end 
     else 
      queue = 'failed_1' 
     end 
     end 
    else 
     queue = 'todo' 
    end 
    end 
end 

EM.run do 
    @redis = EM::Hiredis.connect "redis://#{HOST}:#{PORT}" 

    # How to get the value of fetch_queue? 
    foo = fetch_queue 
    puts foo 
end 

我的問題是:我怎麼能告訴他們返回在「fetch_queue」排隊'的值在反應器循環使用它? fetch_queue中的一個簡單的「返回隊列='todo'」,「返回隊列='failed_1'」等等會導致「意外返回(LocalJumpError)」錯誤消息。

回答

9

請爲調試的愛使用更多的方法,你不會考慮這樣的其他代碼,你會嗎?

無論如何,這基本上是什麼,你可能想要做的,所以你既可以因子和測試代碼:

require 'eventmachine' 
require 'em-hiredis' 

# This is a simple class that represents an extremely simple, linear state 
# machine. It just walks the "from" parameter one by one, until it finds a 
# non-empty set by that name. When a non-empty set is found, the given callback 
# is called with the name of the set. 
class Finder 

    def initialize(redis, from, &callback) 
    @redis = redis 
    @from = from.dup 
    @callback = callback 
    end 

    def do_next 
    # If the from list is empty, we terminate, as we have no more steps 
    unless @current = @from.shift 
     EM.stop # or callback.call :error, whatever 
    end 

    @redis.scard(@current).callback do |scard| 
     if scard.zero? 
     do_next 
     else 
     @callback.call @current 
     end 
    end 
    end 

    alias go do_next 

end 

EM.run do 
    @redis = EM::Hiredis.connect "redis://#{HOST}:#{PORT}" 

    finder = Finder.new(redis, %w[todo failed_1 failed_2 failed_3]) do |name| 
    puts "Found non-empty set: #{name}" 
    end 

    finder.go 
end 
+0

哇,多麼aswer!非常感謝raggi這樣一個很酷和詳細的樣本! – ctp 2012-04-25 11:02:59