SlideShare a Scribd company logo
1 of 53
No Callbacks, No Threads & Ruby 1.9 async & co-operative web-servers Ilya Grigorik @igrigorik
The slides… Twitter My blog
The state of art is not good enough. (we’ve been stuck in the same local minima for several years)
require"active_record” ActiveRecord::Base.establish_connection(   :adapter => "mysql",   :username => "root",   :database => "database",   :pool => 5 ) threads = [] 10.times do |n|    threads <<Thread.new { ActiveRecord::Base.connection_pool.with_connectiondo |conn|       res =conn.execute("select sleep(1)") end   } end threads.each { |t| t.join } The “Experiment” vanilla everything…
require"active_record” ActiveRecord::Base.establish_connection(   :adapter => "mysql",   :username => "root",   :database => "database",   :pool => 5 ) threads = [] 10.times do |n|    threads <<Thread.new { ActiveRecord::Base.connection_pool.with_connectiondo |conn|       res =conn.execute("select sleep(1)") end   } end threads.each { |t| t.join } 5 shared connections # time ruby activerecord-pool.rb # # real    0m10.663s # user    0m0.405s # sys     0m0.201s
BHP % power      loss WHP
> 50% power loss!?
Mongo Couch MySQL PSQL … Drivers Threads Ruby VM GIL Fibers … Network Mongrel Unicorn Passenger …
2 Mongo Couch MySQL PSQL … Drivers Threads Ruby VM 1 4 GIL Fibers … Network Mongrel Unicorn 3 We’re as fast as the slowest component Passenger …
Global Interpreter Lock is a mutual exclusion lock held by a programming language interpreter thread to avoid sharing code that is not thread-safe with other threads.  There is always one GIL for one interpreter process. Concurrency is a myth in Ruby (with a few caveats, of course) http://bit.ly/ruby-gil
N-M thread pool in Ruby 1.9… Better but still the same problem! Concurrency is a myth in Ruby still no concurrency in Ruby 1.9 http://bit.ly/ruby-gil
Nick – tomorrow @ 11:45am Concurrency is a myth in Ruby still no concurrency in Ruby 1.9 http://bit.ly/ruby-gil
Blocks entire Ruby VM Not as bad, but avoid it still.. Avoid locking interpreter threads at all costs let’s say you’re writing an extension…
Will fetch_xyz() block the VM? when was the last time you asked yourself this question?
require 'rubygems’ require 'sequel'DB = Sequel.connect('mysql://root@localhost/test')while trueDB['select sleep(1)'].select.firstend Blocking 1s call! ltrace –ttTg -xmysql_real_query –p ./example.rb mysql.gem under the hood 22:10:00.218438 mysql_real_query(0x02740000, "select sleep(1)", 15) = 0 <1.001100>22:10:01.241679 mysql_real_query(0x02740000, "select sleep(1)", 15) = 0 <1.000812> http://bit.ly/c3Pt3f
Blocking calls to mysql_real_query mysql_real_query requires an OS thread Blocking on mysql_real_query blocks the Ruby VM Aka, “select sleep(1)” blocks the entire Ruby runtime for 1s (ouch) gem install mysqlwhat you didn’t know…
static VALUE async_query(intargc, VALUE* argv, VALUE obj) {   ... send_query( obj, sql );   ... schedule_query( obj, timeout);   ... returnget_result(obj);  } staticvoidschedule_query(VALUEobj, VALUE timeout) {   ... structtimevaltv = { tv_sec: timeout, tv_usec: 0 }; for(;;){ FD_ZERO(&read); FD_SET(m->net.fd, &read);     ret = rb_thread_select(m->net.fd + 1, &read, NULL, NULL, &tv);     ... if (m->status == MYSQL_STATUS_READY) break;  } } send query and block Ruby: select() = C: rb_thread_select() mysqlplus.gem under the hood
spinning in select mysqlplus.gem + ruby select
Step 1: Fix the drivers Many of our DB drivers don’t respect the  underlying Ruby VM. Don’t blame the VM.
Drivers Ruby VM Network WEBRick Mongrel made Rails viable still powers a lot of Rails apps today
Rails rediscovers Apache the worker/forker model…
*nix IPC is fast!  Woo! … Full Ruby VM An exclusive Ruby VM for EACH request am I the only one who thinks this is terrible?
“Does not care if your application is thread-safe or not, workers all run within their own isolated address space and only serve one client at a time for maximum robustness.” Robustness? That sounds like a bug. An exclusive Ruby VM for EACH request am I the only one who thinks this is terrible?
Step 2: consider entire stack The driver, the web-server, and the network must all work together.
Node imposes the full-stack requirements Node imposes async drivers Node imposes async frameworks Surprise: Node is “fast”
We can ignore the performance issues at our own peril or, we can just fix the problem
> I’ll take Ruby over JS gem install eventmachine
p "Starting"EM.rundop"Running in EM reactor"endp”won’t get here" whiletruedo        timersnetwork_ioother_io end EventMachine Reactor concurrency without thread EventMachine: The Speed DemonWednesday @ 11:45am – Aman Gupta
Non-blocking IO requires non-blocking drivers: AMQP                        http://github.com/tmm1/amqp MySQLPlushttp://github.com/igrigorik/em-mysqlplus Memcachedhttp://github.com/astro/remcached DNS                            http://github.com/astro/em-dns Redishttp://github.com/madsimian/em-redis MongoDBhttp://github.com/tmm1/rmongo HTTPRequesthttp://github.com/igrigorik/em-http-request WebSockethttp://github.com/igrigorik/em-websocket Amazon S3               http://github.com/peritor/happening And many others:  http://wiki.github.com/eventmachine/eventmachine/protocol-implementations
gem install em-mysqlplus EventMachine.rundo conn=EventMachine::MySQL.new(:host => 'localhost')   query =conn.query("select sleep(1)") query.callback { |res| pres.all_hashes } query.errback  { |res| pres.all_hashes }   puts ”executing…” end # > ruby em-mysql-test.rb # # executing… # [{"sleep(1)"=>"0"}] callback fired 1s after “executing” em-mysqlplus: example asyncMySQL driver
non-blocking driver require'mysqlplus' defconnect(opts) conn=connect_socket(opts) EM.watch(conn.socket, EventMachine::MySQLConnection, conn, opts, self) end defconnect_socket(opts) conn=Mysql.init conn.real_connect(host, user, pass, db, port, socket, ...) conn.reconnect=false conn end EM.watch:  reactor will poll & notify em-mysqlplus: under the hood mysqlplus + reactor loop
Features: ,[object Object]
Deferrables for every query with callback & errback
 Connection query queue - pile 'em up!
 Auto-reconnect on disconnects
 Auto-retry on deadlockshttp://github.com/igrigorik/em-mysqlplus em-mysqlplus mysqlplus + reactor loop
and this callback goes to…
We can do better than node.js all the benefits of evented code without the drawbacks
Ruby 1.9 Fibers are a means of creating code blocks which can be paused and resumed by our application (think lightweight threads, minus the thread scheduler and less overhead).  f=Fiber.new { whiletruedo Fiber.yield"Hi” end } pf.resume# => Hi pf.resume# => Hi pf.resume# => Hi Manual / cooperative scheduling! Ruby 1.9 Fibers and cooperative scheduling http://bit.ly/d2hYw0
Fibers vs Threads: creation time much lower Fibers vs Threads: memory usage is much lower Ruby 1.9 Fibers and cooperative scheduling http://bit.ly/aesXy5
defquery(sql) f = Fiber.current conn=EventMachine::MySQL.new(:host => 'localhost') q = conn.query(sql) c.callback { f.resume(conn) } c.errback  { f.resume(conn) } return Fiber.yield end EventMachine.rundo Fiber.new {     res =query('select sleep(1)')     puts "Results: #{res.fetch_row.first}" }.resume end Exception, async! Untangling Evented Code with Fibers http://bit.ly/d2hYw0
defquery(sql) f = Fiber.current conn=EventMachine::MySQL.new(:host => 'localhost') q = conn.query(sql) c.callback { f.resume(conn) } c.errback  { f.resume(conn) }   return Fiber.yield end EventMachine.rundo Fiber.new{     res =query('select sleep(1)')     puts "Results: #{res.fetch_row.first}"   }.resume end 1. Wrap into a continuation Untangling Evented Code with Fibers http://bit.ly/d2hYw0
defquery(sql) f=Fiber.current conn=EventMachine::MySQL.new(:host => 'localhost') q = conn.query(sql) c.callback { f.resume(conn) } c.errback  { f.resume(conn) } returnFiber.yield end EventMachine.rundo Fiber.new{     res =query('select sleep(1)')     puts "Results: #{res.fetch_row.first}"   }.resume end 2. Pause the continuation Untangling Evented Code with Fibers http://bit.ly/d2hYw0
defquery(sql) f=Fiber.current conn=EventMachine::MySQL.new(:host => 'localhost') q = conn.query(sql) c.callback { f.resume(conn) } c.errback  { f.resume(conn) } returnFiber.yield end EventMachine.rundo Fiber.new{     res =query('select sleep(1)')     puts "Results: #{res.fetch_row.first}"   }.resume end 3. Resume the continuation Untangling Evented Code with Fibers http://bit.ly/d2hYw0
Good news, you don’t even have to muck around with Fibers! gem install em-synchrony http://github.com/igrigorik/em-synchrony ,[object Object]
 Multi request interface which accepts any callback enabled client
 Fibered iterator to allow concurrency control & mixing of sync / async
em-http-request: .get, etc are synchronous, while .aget, etc are async
em-mysqlplus: .query is synchronous, while .aquery is async

More Related Content

What's hot

How NOT to write in Node.js
How NOT to write in Node.jsHow NOT to write in Node.js
How NOT to write in Node.jsPiotr Pelczar
 
Comet with node.js and V8
Comet with node.js and V8Comet with node.js and V8
Comet with node.js and V8amix3k
 
Introduction to Python Celery
Introduction to Python CeleryIntroduction to Python Celery
Introduction to Python CeleryMahendra M
 
Ruby Proxies for Scale, Performance, and Monitoring
Ruby Proxies for Scale, Performance, and MonitoringRuby Proxies for Scale, Performance, and Monitoring
Ruby Proxies for Scale, Performance, and MonitoringIlya Grigorik
 
OSCON 2011 - Node.js Tutorial
OSCON 2011 - Node.js TutorialOSCON 2011 - Node.js Tutorial
OSCON 2011 - Node.js TutorialTom Croucher
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tourcacois
 
Data processing with celery and rabbit mq
Data processing with celery and rabbit mqData processing with celery and rabbit mq
Data processing with celery and rabbit mqJeff Peck
 
Non-blocking I/O, Event loops and node.js
Non-blocking I/O, Event loops and node.jsNon-blocking I/O, Event loops and node.js
Non-blocking I/O, Event loops and node.jsMarcus Frödin
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Javascript Promises/Q Library
Javascript Promises/Q LibraryJavascript Promises/Q Library
Javascript Promises/Q Libraryasync_io
 
Celery: The Distributed Task Queue
Celery: The Distributed Task QueueCelery: The Distributed Task Queue
Celery: The Distributed Task QueueRichard Leland
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with ExamplesGabriele Lana
 
Node js presentation
Node js presentationNode js presentation
Node js presentationmartincabrera
 
JavaScript Engines and Event Loop
JavaScript Engines and Event Loop JavaScript Engines and Event Loop
JavaScript Engines and Event Loop Tapan B.K.
 
Avoiding callback hell with promises
Avoiding callback hell with promisesAvoiding callback hell with promises
Avoiding callback hell with promisesTorontoNodeJS
 
Celery for internal API in SOA infrastructure
Celery for internal API in SOA infrastructureCelery for internal API in SOA infrastructure
Celery for internal API in SOA infrastructureRoman Imankulov
 
Scaling up task processing with Celery
Scaling up task processing with CeleryScaling up task processing with Celery
Scaling up task processing with CeleryNicolas Grasset
 
A million connections and beyond - Node.js at scale
A million connections and beyond - Node.js at scaleA million connections and beyond - Node.js at scale
A million connections and beyond - Node.js at scaleTom Croucher
 
Why and how Pricing Assistant migrated from Celery to RQ - Paris.py #2
Why and how Pricing Assistant migrated from Celery to RQ - Paris.py #2Why and how Pricing Assistant migrated from Celery to RQ - Paris.py #2
Why and how Pricing Assistant migrated from Celery to RQ - Paris.py #2Sylvain Zimmer
 

What's hot (20)

JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
How NOT to write in Node.js
How NOT to write in Node.jsHow NOT to write in Node.js
How NOT to write in Node.js
 
Comet with node.js and V8
Comet with node.js and V8Comet with node.js and V8
Comet with node.js and V8
 
Introduction to Python Celery
Introduction to Python CeleryIntroduction to Python Celery
Introduction to Python Celery
 
Ruby Proxies for Scale, Performance, and Monitoring
Ruby Proxies for Scale, Performance, and MonitoringRuby Proxies for Scale, Performance, and Monitoring
Ruby Proxies for Scale, Performance, and Monitoring
 
OSCON 2011 - Node.js Tutorial
OSCON 2011 - Node.js TutorialOSCON 2011 - Node.js Tutorial
OSCON 2011 - Node.js Tutorial
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tour
 
Data processing with celery and rabbit mq
Data processing with celery and rabbit mqData processing with celery and rabbit mq
Data processing with celery and rabbit mq
 
Non-blocking I/O, Event loops and node.js
Non-blocking I/O, Event loops and node.jsNon-blocking I/O, Event loops and node.js
Non-blocking I/O, Event loops and node.js
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Javascript Promises/Q Library
Javascript Promises/Q LibraryJavascript Promises/Q Library
Javascript Promises/Q Library
 
Celery: The Distributed Task Queue
Celery: The Distributed Task QueueCelery: The Distributed Task Queue
Celery: The Distributed Task Queue
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with Examples
 
Node js presentation
Node js presentationNode js presentation
Node js presentation
 
JavaScript Engines and Event Loop
JavaScript Engines and Event Loop JavaScript Engines and Event Loop
JavaScript Engines and Event Loop
 
Avoiding callback hell with promises
Avoiding callback hell with promisesAvoiding callback hell with promises
Avoiding callback hell with promises
 
Celery for internal API in SOA infrastructure
Celery for internal API in SOA infrastructureCelery for internal API in SOA infrastructure
Celery for internal API in SOA infrastructure
 
Scaling up task processing with Celery
Scaling up task processing with CeleryScaling up task processing with Celery
Scaling up task processing with Celery
 
A million connections and beyond - Node.js at scale
A million connections and beyond - Node.js at scaleA million connections and beyond - Node.js at scale
A million connections and beyond - Node.js at scale
 
Why and how Pricing Assistant migrated from Celery to RQ - Paris.py #2
Why and how Pricing Assistant migrated from Celery to RQ - Paris.py #2Why and how Pricing Assistant migrated from Celery to RQ - Paris.py #2
Why and how Pricing Assistant migrated from Celery to RQ - Paris.py #2
 

Viewers also liked

"MySQL Boosting - DB Best Practices & Optimization" by José Luis Martínez - C...
"MySQL Boosting - DB Best Practices & Optimization" by José Luis Martínez - C..."MySQL Boosting - DB Best Practices & Optimization" by José Luis Martínez - C...
"MySQL Boosting - DB Best Practices & Optimization" by José Luis Martínez - C...CAPSiDE
 
Celluloid, Celluloid::IO and Friends
Celluloid, Celluloid::IO and FriendsCelluloid, Celluloid::IO and Friends
Celluloid, Celluloid::IO and FriendsMarcelo Pinheiro
 
Hybrid concurrency patterns
Hybrid concurrency patternsHybrid concurrency patterns
Hybrid concurrency patternsKyle Drake
 
Buffer pool implementaion inno db vs oracle
Buffer pool implementaion inno db vs oracleBuffer pool implementaion inno db vs oracle
Buffer pool implementaion inno db vs oraclefrogd
 
Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략Jin wook
 
mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교Woo Yeong Choi
 

Viewers also liked (7)

"MySQL Boosting - DB Best Practices & Optimization" by José Luis Martínez - C...
"MySQL Boosting - DB Best Practices & Optimization" by José Luis Martínez - C..."MySQL Boosting - DB Best Practices & Optimization" by José Luis Martínez - C...
"MySQL Boosting - DB Best Practices & Optimization" by José Luis Martínez - C...
 
Celluloid, Celluloid::IO and Friends
Celluloid, Celluloid::IO and FriendsCelluloid, Celluloid::IO and Friends
Celluloid, Celluloid::IO and Friends
 
Actor model in Ruby
Actor model in RubyActor model in Ruby
Actor model in Ruby
 
Hybrid concurrency patterns
Hybrid concurrency patternsHybrid concurrency patterns
Hybrid concurrency patterns
 
Buffer pool implementaion inno db vs oracle
Buffer pool implementaion inno db vs oracleBuffer pool implementaion inno db vs oracle
Buffer pool implementaion inno db vs oracle
 
Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략
 
mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교
 

Similar to No Callbacks, No Threads - RailsConf 2010

No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9Ilya Grigorik
 
Complex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxComplex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxbobmcwhirter
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the wayOleg Podsechin
 
Node.js: CAMTA Presentation
Node.js: CAMTA PresentationNode.js: CAMTA Presentation
Node.js: CAMTA PresentationRob Tweed
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725miguel dominguez
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725MortazaJohari
 
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Yevgeniy Brikman
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.jsJack Franklin
 
Original slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talkOriginal slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talkAarti Parikh
 
Going Live! with Comet
Going Live! with CometGoing Live! with Comet
Going Live! with CometSimon Willison
 
Analysis bottleneck in J2EE application
Analysis bottleneck in J2EE applicationAnalysis bottleneck in J2EE application
Analysis bottleneck in J2EE applicationTerry Cho
 
Find bottleneck and tuning in Java Application
Find bottleneck and tuning in Java ApplicationFind bottleneck and tuning in Java Application
Find bottleneck and tuning in Java Applicationguest1f2740
 
Deployment with Fabric
Deployment with FabricDeployment with Fabric
Deployment with Fabricandymccurdy
 
Real World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS ApplicationReal World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS ApplicationBen Hall
 
JavaScript is the new black - Why Node.js is going to rock your world - Web 2...
JavaScript is the new black - Why Node.js is going to rock your world - Web 2...JavaScript is the new black - Why Node.js is going to rock your world - Web 2...
JavaScript is the new black - Why Node.js is going to rock your world - Web 2...Tom Croucher
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.jsChris Cowan
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011tobiascrawley
 

Similar to No Callbacks, No Threads - RailsConf 2010 (20)

No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
 
Complex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxComplex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBox
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
Node.js: CAMTA Presentation
Node.js: CAMTA PresentationNode.js: CAMTA Presentation
Node.js: CAMTA Presentation
 
Node.js
Node.jsNode.js
Node.js
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
 
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Original slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talkOriginal slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talk
 
Going Live! with Comet
Going Live! with CometGoing Live! with Comet
Going Live! with Comet
 
Analysis bottleneck in J2EE application
Analysis bottleneck in J2EE applicationAnalysis bottleneck in J2EE application
Analysis bottleneck in J2EE application
 
Find bottleneck and tuning in Java Application
Find bottleneck and tuning in Java ApplicationFind bottleneck and tuning in Java Application
Find bottleneck and tuning in Java Application
 
Deployment with Fabric
Deployment with FabricDeployment with Fabric
Deployment with Fabric
 
Real World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS ApplicationReal World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS Application
 
Nodejs Intro Part One
Nodejs Intro Part OneNodejs Intro Part One
Nodejs Intro Part One
 
JavaScript is the new black - Why Node.js is going to rock your world - Web 2...
JavaScript is the new black - Why Node.js is going to rock your world - Web 2...JavaScript is the new black - Why Node.js is going to rock your world - Web 2...
JavaScript is the new black - Why Node.js is going to rock your world - Web 2...
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.js
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
 

More from Ilya Grigorik

Pagespeed what, why, and how it works
Pagespeed   what, why, and how it worksPagespeed   what, why, and how it works
Pagespeed what, why, and how it worksIlya Grigorik
 
Making the web fast(er) - RailsConf 2012
Making the web fast(er) - RailsConf 2012Making the web fast(er) - RailsConf 2012
Making the web fast(er) - RailsConf 2012Ilya Grigorik
 
0-60 with Goliath: High performance web services
0-60 with Goliath: High performance web services0-60 with Goliath: High performance web services
0-60 with Goliath: High performance web servicesIlya Grigorik
 
Ruby in the Browser - RubyConf 2011
Ruby in the Browser - RubyConf 2011Ruby in the Browser - RubyConf 2011
Ruby in the Browser - RubyConf 2011Ilya Grigorik
 
Intelligent Ruby + Machine Learning
Intelligent Ruby + Machine LearningIntelligent Ruby + Machine Learning
Intelligent Ruby + Machine LearningIlya Grigorik
 
Real-time Ruby for the Real-time Web
Real-time Ruby for the Real-time WebReal-time Ruby for the Real-time Web
Real-time Ruby for the Real-time WebIlya Grigorik
 
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09Ilya Grigorik
 
Leveraging Social Media - Strategies & Tactics - PostRank
Leveraging Social Media - Strategies & Tactics - PostRankLeveraging Social Media - Strategies & Tactics - PostRank
Leveraging Social Media - Strategies & Tactics - PostRankIlya Grigorik
 
Building Mini Google in Ruby
Building Mini Google in RubyBuilding Mini Google in Ruby
Building Mini Google in RubyIlya Grigorik
 
Event Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya GrigorikEvent Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya GrigorikIlya Grigorik
 
Taming The RSS Beast
Taming The  RSS  BeastTaming The  RSS  Beast
Taming The RSS BeastIlya Grigorik
 

More from Ilya Grigorik (11)

Pagespeed what, why, and how it works
Pagespeed   what, why, and how it worksPagespeed   what, why, and how it works
Pagespeed what, why, and how it works
 
Making the web fast(er) - RailsConf 2012
Making the web fast(er) - RailsConf 2012Making the web fast(er) - RailsConf 2012
Making the web fast(er) - RailsConf 2012
 
0-60 with Goliath: High performance web services
0-60 with Goliath: High performance web services0-60 with Goliath: High performance web services
0-60 with Goliath: High performance web services
 
Ruby in the Browser - RubyConf 2011
Ruby in the Browser - RubyConf 2011Ruby in the Browser - RubyConf 2011
Ruby in the Browser - RubyConf 2011
 
Intelligent Ruby + Machine Learning
Intelligent Ruby + Machine LearningIntelligent Ruby + Machine Learning
Intelligent Ruby + Machine Learning
 
Real-time Ruby for the Real-time Web
Real-time Ruby for the Real-time WebReal-time Ruby for the Real-time Web
Real-time Ruby for the Real-time Web
 
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09
 
Leveraging Social Media - Strategies & Tactics - PostRank
Leveraging Social Media - Strategies & Tactics - PostRankLeveraging Social Media - Strategies & Tactics - PostRank
Leveraging Social Media - Strategies & Tactics - PostRank
 
Building Mini Google in Ruby
Building Mini Google in RubyBuilding Mini Google in Ruby
Building Mini Google in Ruby
 
Event Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya GrigorikEvent Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya Grigorik
 
Taming The RSS Beast
Taming The  RSS  BeastTaming The  RSS  Beast
Taming The RSS Beast
 

Recently uploaded

A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 

Recently uploaded (20)

A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 

No Callbacks, No Threads - RailsConf 2010

  • 1. No Callbacks, No Threads & Ruby 1.9 async & co-operative web-servers Ilya Grigorik @igrigorik
  • 3. The state of art is not good enough. (we’ve been stuck in the same local minima for several years)
  • 4. require"active_record” ActiveRecord::Base.establish_connection( :adapter => "mysql", :username => "root", :database => "database", :pool => 5 ) threads = [] 10.times do |n| threads <<Thread.new { ActiveRecord::Base.connection_pool.with_connectiondo |conn| res =conn.execute("select sleep(1)") end } end threads.each { |t| t.join } The “Experiment” vanilla everything…
  • 5. require"active_record” ActiveRecord::Base.establish_connection( :adapter => "mysql", :username => "root", :database => "database", :pool => 5 ) threads = [] 10.times do |n| threads <<Thread.new { ActiveRecord::Base.connection_pool.with_connectiondo |conn| res =conn.execute("select sleep(1)") end } end threads.each { |t| t.join } 5 shared connections # time ruby activerecord-pool.rb # # real 0m10.663s # user 0m0.405s # sys 0m0.201s
  • 6.
  • 7. BHP % power loss WHP
  • 8.
  • 9.
  • 10. > 50% power loss!?
  • 11. Mongo Couch MySQL PSQL … Drivers Threads Ruby VM GIL Fibers … Network Mongrel Unicorn Passenger …
  • 12. 2 Mongo Couch MySQL PSQL … Drivers Threads Ruby VM 1 4 GIL Fibers … Network Mongrel Unicorn 3 We’re as fast as the slowest component Passenger …
  • 13. Global Interpreter Lock is a mutual exclusion lock held by a programming language interpreter thread to avoid sharing code that is not thread-safe with other threads. There is always one GIL for one interpreter process. Concurrency is a myth in Ruby (with a few caveats, of course) http://bit.ly/ruby-gil
  • 14. N-M thread pool in Ruby 1.9… Better but still the same problem! Concurrency is a myth in Ruby still no concurrency in Ruby 1.9 http://bit.ly/ruby-gil
  • 15. Nick – tomorrow @ 11:45am Concurrency is a myth in Ruby still no concurrency in Ruby 1.9 http://bit.ly/ruby-gil
  • 16. Blocks entire Ruby VM Not as bad, but avoid it still.. Avoid locking interpreter threads at all costs let’s say you’re writing an extension…
  • 17. Will fetch_xyz() block the VM? when was the last time you asked yourself this question?
  • 18. require 'rubygems’ require 'sequel'DB = Sequel.connect('mysql://root@localhost/test')while trueDB['select sleep(1)'].select.firstend Blocking 1s call! ltrace –ttTg -xmysql_real_query –p ./example.rb mysql.gem under the hood 22:10:00.218438 mysql_real_query(0x02740000, "select sleep(1)", 15) = 0 <1.001100>22:10:01.241679 mysql_real_query(0x02740000, "select sleep(1)", 15) = 0 <1.000812> http://bit.ly/c3Pt3f
  • 19. Blocking calls to mysql_real_query mysql_real_query requires an OS thread Blocking on mysql_real_query blocks the Ruby VM Aka, “select sleep(1)” blocks the entire Ruby runtime for 1s (ouch) gem install mysqlwhat you didn’t know…
  • 20. static VALUE async_query(intargc, VALUE* argv, VALUE obj) { ... send_query( obj, sql ); ... schedule_query( obj, timeout); ... returnget_result(obj); } staticvoidschedule_query(VALUEobj, VALUE timeout) { ... structtimevaltv = { tv_sec: timeout, tv_usec: 0 }; for(;;){ FD_ZERO(&read); FD_SET(m->net.fd, &read); ret = rb_thread_select(m->net.fd + 1, &read, NULL, NULL, &tv); ... if (m->status == MYSQL_STATUS_READY) break; } } send query and block Ruby: select() = C: rb_thread_select() mysqlplus.gem under the hood
  • 21. spinning in select mysqlplus.gem + ruby select
  • 22. Step 1: Fix the drivers Many of our DB drivers don’t respect the underlying Ruby VM. Don’t blame the VM.
  • 23. Drivers Ruby VM Network WEBRick Mongrel made Rails viable still powers a lot of Rails apps today
  • 24. Rails rediscovers Apache the worker/forker model…
  • 25. *nix IPC is fast! Woo! … Full Ruby VM An exclusive Ruby VM for EACH request am I the only one who thinks this is terrible?
  • 26. “Does not care if your application is thread-safe or not, workers all run within their own isolated address space and only serve one client at a time for maximum robustness.” Robustness? That sounds like a bug. An exclusive Ruby VM for EACH request am I the only one who thinks this is terrible?
  • 27.
  • 28. Step 2: consider entire stack The driver, the web-server, and the network must all work together.
  • 29. Node imposes the full-stack requirements Node imposes async drivers Node imposes async frameworks Surprise: Node is “fast”
  • 30. We can ignore the performance issues at our own peril or, we can just fix the problem
  • 31. > I’ll take Ruby over JS gem install eventmachine
  • 32. p "Starting"EM.rundop"Running in EM reactor"endp”won’t get here" whiletruedo timersnetwork_ioother_io end EventMachine Reactor concurrency without thread EventMachine: The Speed DemonWednesday @ 11:45am – Aman Gupta
  • 33. Non-blocking IO requires non-blocking drivers: AMQP http://github.com/tmm1/amqp MySQLPlushttp://github.com/igrigorik/em-mysqlplus Memcachedhttp://github.com/astro/remcached DNS http://github.com/astro/em-dns Redishttp://github.com/madsimian/em-redis MongoDBhttp://github.com/tmm1/rmongo HTTPRequesthttp://github.com/igrigorik/em-http-request WebSockethttp://github.com/igrigorik/em-websocket Amazon S3 http://github.com/peritor/happening And many others: http://wiki.github.com/eventmachine/eventmachine/protocol-implementations
  • 34. gem install em-mysqlplus EventMachine.rundo conn=EventMachine::MySQL.new(:host => 'localhost') query =conn.query("select sleep(1)") query.callback { |res| pres.all_hashes } query.errback { |res| pres.all_hashes } puts ”executing…” end # > ruby em-mysql-test.rb # # executing… # [{"sleep(1)"=>"0"}] callback fired 1s after “executing” em-mysqlplus: example asyncMySQL driver
  • 35. non-blocking driver require'mysqlplus' defconnect(opts) conn=connect_socket(opts) EM.watch(conn.socket, EventMachine::MySQLConnection, conn, opts, self) end defconnect_socket(opts) conn=Mysql.init conn.real_connect(host, user, pass, db, port, socket, ...) conn.reconnect=false conn end EM.watch: reactor will poll & notify em-mysqlplus: under the hood mysqlplus + reactor loop
  • 36.
  • 37. Deferrables for every query with callback & errback
  • 38. Connection query queue - pile 'em up!
  • 39. Auto-reconnect on disconnects
  • 40. Auto-retry on deadlockshttp://github.com/igrigorik/em-mysqlplus em-mysqlplus mysqlplus + reactor loop
  • 41. and this callback goes to…
  • 42. We can do better than node.js all the benefits of evented code without the drawbacks
  • 43. Ruby 1.9 Fibers are a means of creating code blocks which can be paused and resumed by our application (think lightweight threads, minus the thread scheduler and less overhead). f=Fiber.new { whiletruedo Fiber.yield"Hi” end } pf.resume# => Hi pf.resume# => Hi pf.resume# => Hi Manual / cooperative scheduling! Ruby 1.9 Fibers and cooperative scheduling http://bit.ly/d2hYw0
  • 44. Fibers vs Threads: creation time much lower Fibers vs Threads: memory usage is much lower Ruby 1.9 Fibers and cooperative scheduling http://bit.ly/aesXy5
  • 45. defquery(sql) f = Fiber.current conn=EventMachine::MySQL.new(:host => 'localhost') q = conn.query(sql) c.callback { f.resume(conn) } c.errback { f.resume(conn) } return Fiber.yield end EventMachine.rundo Fiber.new { res =query('select sleep(1)') puts "Results: #{res.fetch_row.first}" }.resume end Exception, async! Untangling Evented Code with Fibers http://bit.ly/d2hYw0
  • 46. defquery(sql) f = Fiber.current conn=EventMachine::MySQL.new(:host => 'localhost') q = conn.query(sql) c.callback { f.resume(conn) } c.errback { f.resume(conn) } return Fiber.yield end EventMachine.rundo Fiber.new{ res =query('select sleep(1)') puts "Results: #{res.fetch_row.first}" }.resume end 1. Wrap into a continuation Untangling Evented Code with Fibers http://bit.ly/d2hYw0
  • 47. defquery(sql) f=Fiber.current conn=EventMachine::MySQL.new(:host => 'localhost') q = conn.query(sql) c.callback { f.resume(conn) } c.errback { f.resume(conn) } returnFiber.yield end EventMachine.rundo Fiber.new{ res =query('select sleep(1)') puts "Results: #{res.fetch_row.first}" }.resume end 2. Pause the continuation Untangling Evented Code with Fibers http://bit.ly/d2hYw0
  • 48. defquery(sql) f=Fiber.current conn=EventMachine::MySQL.new(:host => 'localhost') q = conn.query(sql) c.callback { f.resume(conn) } c.errback { f.resume(conn) } returnFiber.yield end EventMachine.rundo Fiber.new{ res =query('select sleep(1)') puts "Results: #{res.fetch_row.first}" }.resume end 3. Resume the continuation Untangling Evented Code with Fibers http://bit.ly/d2hYw0
  • 49.
  • 50. Multi request interface which accepts any callback enabled client
  • 51. Fibered iterator to allow concurrency control & mixing of sync / async
  • 52. em-http-request: .get, etc are synchronous, while .aget, etc are async
  • 53. em-mysqlplus: .query is synchronous, while .aquery is async
  • 54. remcached: .get, etc, and .multi_* methods are synchronousem-synchrony: simple evented programming best of both worlds…
  • 55. require"em-synchrony/em-mysqlplus" EventMachine.synchronydo db =EventMachine::MySQL.new(host:"localhost") res =db.query("select sleep(1)") puts res EventMachine.stop end Async under the hood Untangling Evented Code with Fibers http://bit.ly/d2hYw0
  • 56. require "em-synchrony/em-mysqlplus" EventMachine.synchrony do db = EventMachine::MySQL.new(host: "localhost") res =db.query("select sleep(1)") puts res EventMachine.stop end Untangling Evented Code with Fibers http://bit.ly/d2hYw0
  • 57. EM-HTTP, EM-MySQL, EM-Jack, etc. Drivers Async-rack Ruby VM Fibers Network Goliath Thin One VM, full concurrency, network-bound Ruby 1.9, Fibers, Thin: in production!
  • 58. git clone git://github.com/igrigorik/em-mysqlplus.git git checkout activerecord rake install database.yml development: adapter:em_mysqlplus database:widgets pool: 5 timeout: 5000 environment.rb require 'em-activerecord’ require 'rack/fiber_pool' # Run each request in a Fiber config.middleware.useRack::FiberPool config.threadsafe! Async Rails with EventMachine & MySQL
  • 59. classWidgetsController< ApplicationController defindex Widget.find_by_sql("select sleep(1)") render:text => "Oh hai” end end ab –c 5 –n 10 http://127.0.0.1:3000/widgets Server Software: thin Server Hostname: 127.0.0.1 Server Port: 3000 Document Path: /widgets/ Document Length: 6 bytes Concurrency Level: 5 Time taken for tests: 2.210 seconds Complete requests: 10 Failed requests: 0 Requests per second: 4.53 [#/sec] (mean) woot! Fiber DB pool at work. Async Rails with EventMachine & MySQL
  • 60. git clone git://…./igrigorik/mysqlplus git checkout activerecord rake install Not only is it doable… it already works.
  • 61. Ruby 1.9 + Rails 3 + new stack = Order of magnitude better performance (aka, enough of a reason to actually switch)
  • 62. The state of art is not good enough, in fact, it’s terrible! Let’s fix it. Fibers & Cooperative Scheduling in Ruby: http://www.igvita.com/2009/05/13/fibers-cooperative-scheduling-in-ruby/ Untangling Evented Code with Ruby Fibers: http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/ EM-Synchrony: http://github.com/igrigorik/em-synchrony What do you think?

Editor's Notes

  1. The blame game.
  2. The blame game.
  3. coroutines
  4. coroutines