Ruby EventMachine和函数

ctp*_*ctp 1 ruby eventmachine redis

我正在使用合适的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
Run Code Online (Sandbox Code Playgroud)

我的问题是:如何告诉EM在'fetch_queue'中返回'queue'的值,以便在reactor循环中使用它?fetch_queue中的简单"return queue ='todo'","return queue ='failed_1'"等会导致"意外返回(LocalJumpError)"错误消息.

rag*_*ggi 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
Run Code Online (Sandbox Code Playgroud)