小编典典

简单使用EM :: Synchrony#sync会导致“根光纤” FiberError —我的错?

redis

这个程序

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>'

我觉得这很令人困惑。为什么它不起作用,我是否有错?如果是这样,我该怎么做?除非我掩盖了某些内容,否则根据em-synchrony自述文件,这是洁食。


阅读 371

收藏
2020-06-20

共1个答案

小编典典

我认为,如果您找到正确的em-hiredis版本并尝试猴子补丁,那么您的代码就可以工作,这是依赖项松散的问题之一。

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

宝石文件:

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

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

2020-06-20