diff --git a/lib/mysql2/em.rb b/lib/mysql2/em.rb index 98da1e6..bfdde70 100644 --- a/lib/mysql2/em.rb +++ b/lib/mysql2/em.rb @@ -23,10 +23,14 @@ module Mysql2 end def query(sql, opts={}) - super(sql, opts.merge(:async => true)) - deferable = ::EM::DefaultDeferrable.new - ::EM.watch(self.socket, Watcher, self, deferable).notify_readable = true - deferable + if ::EM.reactor_running? + super(sql, opts.merge(:async => true)) + deferable = ::EM::DefaultDeferrable.new + ::EM.watch(self.socket, Watcher, self, deferable).notify_readable = true + deferable + else + super(sql, opts) + end end end end diff --git a/lib/mysql2/em_fiber.rb b/lib/mysql2/em_fiber.rb new file mode 100644 index 0000000..9d793ae --- /dev/null +++ b/lib/mysql2/em_fiber.rb @@ -0,0 +1,29 @@ +# encoding: utf-8 + +require 'mysql2/em' +require 'fiber' + +module Mysql2 + module EM + module Fiber + class Client < ::Mysql2::EM::Client + def query(sql, opts={}) + if ::EM.reactor_running? + deferable = super(sql, opts) + + fiber = ::Fiber.current + deferable.callback do |result| + fiber.resume(result) + end + deferable.errback do |err| + fiber.resume(err) + end + ::Fiber.yield + else + super(sql, opts) + end + end + end + end + end +end diff --git a/mysql2.gemspec b/mysql2.gemspec index a13e9b8..b07f0df 100644 --- a/mysql2.gemspec +++ b/mysql2.gemspec @@ -46,6 +46,7 @@ Gem::Specification.new do |s| "lib/mysql2.rb", "lib/mysql2/client.rb", "lib/mysql2/em.rb", + "lib/mysql2/em_fiber.rb", "lib/mysql2/error.rb", "lib/mysql2/result.rb", "mysql2.gemspec", diff --git a/spec/em/em_fiber_spec.rb b/spec/em/em_fiber_spec.rb new file mode 100644 index 0000000..91b294e --- /dev/null +++ b/spec/em/em_fiber_spec.rb @@ -0,0 +1,22 @@ +# encoding: UTF-8 +if defined? EventMachine && defined? Fiber + require 'spec_helper' + require 'mysql2/em_fiber' + + describe Mysql2::EM::Fiber::Client do + it 'should support queries' do + results = [] + EM.run do + Fiber.new { + client1 = Mysql2::EM::Fiber::Client.new + results = client1.query "SELECT sleep(0.1) as first_query" + EM.stop_event_loop + }.resume + end + + results.first.keys.should include("first_query") + end + end +else + puts "Either EventMachine or Fibers not available. Skipping tests that use them." +end \ No newline at end of file