1

我正在使用合适的 Redis EM gem(在我的例子中为“em-hiredis”)读取 EventMachine 反应器循环中的 Redis 集,并且必须检查某些 Redis 集是否包含级联中的成员。我的目标是获取不为空的集合名称:

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

我的问题是:我如何告诉 EM 在 'fetch_queue' 中返回 'queue' 的值以在反应器循环中使用它?fetch_queue 中的简单“返回队列 = 'todo'”、“返回队列 = 'failed_1'”等会导致“意外返回 (LocalJumpError)”错误消息。

4

1 回答 1

9

Please for the love of debugging use some more methods, you wouldn't factor other code like this, would you?

Anyway, this is essentially what you probably want to do, so you can both factor and test your code:

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
于 2012-04-25T05:32:11.727 回答