Permalink
Browse files

move mysql2 fiber support into synchrony

  • Loading branch information...
1 parent 764fbac commit 2bf309be22e28de223844241e92dde98a8da01a2 @igrigorik committed Aug 27, 2011
Showing with 137 additions and 3 deletions.
  1. +1 −2 Gemfile
  2. +25 −0 lib/em-synchrony/mysql2.rb
  3. +1 −1 spec/helper/all.rb
  4. +110 −0 spec/mysql2_spec.rb
View
@@ -9,8 +9,7 @@ group :development do
# gem 'em-mongo', :git => 'https://github.com/bcg/em-mongo.git'
gem 'em-mongo', '~> 0.3.6'
gem 'bson_ext'
- gem 'mysqlplus'
- gem 'em-mysqlplus'
+ gem 'mysql2'
gem 'em-redis', '~> 0.3.0'
gem 'em-hiredis'
gem 'mongo'
View
@@ -0,0 +1,25 @@
+begin
+ require 'mysql2/em'
+rescue LoadError => error
+ raise 'Missing EM-Synchrony dependency: gem install mysql2'
+end
+
+module Mysql2
+ module EM
+ class Client
+
+ alias :aquery :query
+ def query(sql, opts={})
+ deferable = aquery(sql, opts)
+
+ f = Fiber.current
+ deferable.callback { |res| f.resume(res) }
+ deferable.errback { |err| f.resume(err) }
+
+ Fiber.yield.tap do |result|
+ raise result if result.is_a?(::Exception)
+ end
+ end
+ end
+ end
+end
View
@@ -4,7 +4,7 @@
require 'lib/em-synchrony'
require 'lib/em-synchrony/em-http'
-require 'lib/em-synchrony/em-mysqlplus'
+require 'lib/em-synchrony/mysql2'
require 'lib/em-synchrony/em-remcached'
require 'lib/em-synchrony/em-memcache'
require 'lib/em-synchrony/em-mongo'
View
@@ -0,0 +1,110 @@
+require "spec/helper/all"
+require "em-synchrony/mysql2"
+
+describe Mysql2::EM::Client do
+
+ DELAY = 0.25
+ QUERY = "SELECT sleep(#{DELAY}) as mysql2_query"
+
+ it "should support queries" do
+ res = []
+ EventMachine.synchrony do
+ db = Mysql2::EM::Client.new
+ res = db.query QUERY
+
+ EventMachine.stop
+ end
+
+ res.first.keys.should include("mysql2_query")
+ end
+
+ it "should fire sequential, synchronous requests" do
+ EventMachine.synchrony do
+ db = Mysql2::EM::Client.new
+
+ start = now
+ res = []
+
+ res.push db.query QUERY
+ res.push db.query QUERY
+ (now - start.to_f).should be_within(DELAY * res.size * 0.15).of(DELAY * res.size)
+
+ EventMachine.stop
+ end
+ end
+
+ it "should have accept a callback, errback on async queries" do
+ EventMachine.synchrony do
+ db = Mysql2::EM::Client.new
+
+ res = db.aquery(QUERY)
+ res.errback {|r| fail }
+ res.callback {|r|
+ r.size.should == 1
+ EventMachine.stop
+ }
+ end
+ end
+
+ it "should fire simultaneous requests via Multi interface" do
+ EventMachine.synchrony do
+
+ db = EventMachine::Synchrony::ConnectionPool.new(size: 2) do
+ Mysql2::EM::Client.new
+ end
+
+ start = now
+
+ multi = EventMachine::Synchrony::Multi.new
+ multi.add :a, db.aquery(QUERY)
+ multi.add :b, db.aquery(QUERY)
+ res = multi.perform
+
+ (now - start.to_f).should be_within(DELAY * 0.15).of(DELAY)
+ res.responses[:callback].size.should == 2
+ res.responses[:errback].size.should == 0
+
+ EventMachine.stop
+ end
+ end
+
+ it "should fire sequential and simultaneous MySQL requests" do
+ EventMachine.synchrony do
+ db = EventMachine::Synchrony::ConnectionPool.new(size: 3) do
+ Mysql2::EM::Client.new
+ end
+
+ start = now
+ res = []
+
+ res.push db.query(QUERY)
+ res.push db.query(QUERY)
+ (now - start.to_f).should be_within(DELAY * res.size * 0.15).of(DELAY * res.size)
+
+ start = now
+
+ multi = EventMachine::Synchrony::Multi.new
+ multi.add :a, db.aquery(QUERY)
+ multi.add :b, db.aquery(QUERY)
+ multi.add :c, db.aquery(QUERY)
+ res = multi.perform
+
+ (now - start.to_f).should be_within(DELAY * 0.15).of(DELAY)
+ res.responses[:callback].size.should == 3
+ res.responses[:errback].size.should == 0
+
+ EventMachine.stop
+ end
+ end
+
+ it "should raise Mysql::Error in case of error" do
+ EventMachine.synchrony do
+ db = Mysql2::EM::Client.new
+ proc {
+ db.query("SELECT * FROM i_hope_this_table_does_not_exist;")
+ }.should raise_error(Mysql2::Error)
+ EventMachine.stop
+ end
+ end
+
+end

0 comments on commit 2bf309b

Please sign in to comment.