【问题标题】:Ruby EventMachine & functionsRuby EventMachine & 函数
【发布时间】:2018-01-24 22:55:32
【问题描述】:

我正在使用合适的 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 中的简单“return queue = 'todo'”、“return queue = 'failed_1'”等会导致“unexpected return (LocalJumpError)”错误消息。

【问题讨论】:

    标签: ruby redis eventmachine


    【解决方案1】:

    出于对调试的热爱,请使用更多方法,您不会像这样考虑其他代码,对吗?

    无论如何,这基本上是您可能想要做的,因此您可以考虑并测试您的代码:

    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
    

    【讨论】:

    • 哇,真是一个回答!非常感谢 raggi 提供了如此酷且详细的示例!
    猜你喜欢
    • 2011-04-29
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多