简单使用EM :: Synchrony#sync导致'根光纤'FiberError - 我的错?

时间:2012-01-05 22:27:35

标签: ruby redis eventmachine

这个程序

require 'em-synchrony' ## v1.0.0                                                                                                                               
require 'em-hiredis'   ## v0.1.0                                                                                                                               

module EventMachine
  module Hiredis
    class Client

      def self.connect(host = 'localhost', port = 6379)
        conn = new(host, port)
        EM::Synchrony.sync conn.connect
    conn
      end

      alias :old_method_missing :method_missing
      def method_missing(sym, *args)
        EM::Synchrony.sync old_method_missing(sym, *args)
      end
    end
  end
end

EventMachine.synchrony do
  redis = EM::Hiredis.connect

  redis.set('foo', 'bar')
  puts redis.get('foo')

  EM.stop
end

像这样死去

$ ruby /tmp/reddy.rb 
/home/blt/.rvm/gems/ruby-1.9.3-p0/gems/em-synchrony-1.0.0/lib/em-synchrony.rb:58:in `yield': can't yield from root fiber (FiberError)
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/em-synchrony-1.0.0/lib/em-synchrony.rb:58:in `sync'
    from /tmp/reddy.rb:16:in `method_missing'
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/em-hiredis-0.1.0/lib/em-hiredis/client.rb:119:in `select'
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/em-hiredis-0.1.0/lib/em-hiredis/client.rb:38:in `block in connect'
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/em-hiredis-0.1.0/lib/em-hiredis/event_emitter.rb:8:in `call'
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/em-hiredis-0.1.0/lib/em-hiredis/event_emitter.rb:8:in `block in emit'
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/em-hiredis-0.1.0/lib/em-hiredis/event_emitter.rb:8:in `each'
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/em-hiredis-0.1.0/lib/em-hiredis/event_emitter.rb:8:in `emit'
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/em-hiredis-0.1.0/lib/em-hiredis/connection.rb:15:in `connection_completed'
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/eventmachine-1.0.0.beta.4/lib/eventmachine.rb:179:in `run_machine'
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/eventmachine-1.0.0.beta.4/lib/eventmachine.rb:179:in `run'
    from /home/blt/.rvm/gems/ruby-1.9.3-p0/gems/em-synchrony-1.0.0/lib/em-synchrony.rb:27:in `synchrony'
    from /tmp/reddy.rb:22:in `<main>'

我觉得这很令人困惑。为什么它不起作用,我有错吗?如果是这样,我可以做些什么?除非我对某些东西进行了掩饰,否则根据同步自述文件,这是犹太人的。

1 个答案:

答案 0 :(得分:1)

我认为你的代码可以正常工作,如果你找到正确版本的em-hiredis它试图修补补丁,这是松散依赖的一个问题。

这是一个完全正常工作的代码,但基于em-synchrony的主分支:

的Gemfile:

source :rubygems

gem 'em-synchrony', :git => "git://github.com/igrigorik/em-synchrony.git"
gem 'em-hiredis', '~> 0.1.0'

test.rb:

require 'rubygems'
require 'bundler/setup'

require 'em-synchrony'
require 'em-synchrony/em-hiredis'

EventMachine.synchrony do
  redis = EM::Hiredis.connect

  redis.set('foo', 'bar')
  puts redis.get('foo')

  EM.stop
end

然后运行:

$ bundle
$ ruby test.rb

猴子修补是修补宝石的一种固有缺陷的方法,除非你确保使用你修补的宝石的确切版本,这是同步应该强制执行或至少检测到的。