这个程序
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自述文件,这是洁食。
我认为,如果您找到正确的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
猴子修补是修补宝石的一种固有的有缺陷的方法,除非您确保使用了修补的宝石的确切版本,这是同步应该执行或至少要检测到的。