本文介绍了简单使用 EM::Synchrony#sync 会导致“根光纤"FiberError——我的错?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个程序

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 README,这是 kosher .

I find this deeply confusing. Why doesn't it work and am I at fault? If so, what can I do differently? Unless I've glossed over something, this is kosher, per the em-synchrony README.

推荐答案

我认为,如果您找到了 em-hiredis 试图修补的正确版本,您的代码就可以工作,这就是松散依赖关系的一个问题.

I think your code can work if you find the correct version of em-hiredis it is trying to monkey patch, that is one problem with loose dependencies.

>

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

Here is a fully working code but based on the master branch of em-synchrony:

宝石文件:

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

Monkey 修补是一种固有缺陷的 gem 修补方式,除非您确保使用的是您修补的 gem 的确切版本,这是 em-synchrony 应该强制执行或至少检测到的.

Monkey patching is an inherently flawed way of patching gems unless you ensure the exact version of the gem you patched is used which is something em-synchrony should enforce or at least detect.

这篇关于简单使用 EM::Synchrony#sync 会导致“根光纤"FiberError——我的错?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 04:03