SlideShare a Scribd company logo
1 of 47
No Callbacks, No Threads & Ruby 1.9 async & co-operative web-servers Ilya Grigorik @igrigorik
Reactor Pattern Review:  State of the art Async Primitives Callbacks & Fibers Async Rails?
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
Mongo Couch MySQL PSQL … Drivers Threads Ruby VM GIL Fibers … Network Mongrel Unicorn 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
Concurrency is a myth in Ruby still no parallelism 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…
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!  … 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?
…?
Node imposes the full-stack requirements Node imposes async drivers Node imposes async frameworks *Surprise*: Node is “fast”
= 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
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 callback fired 1s after “executing” # > ruby em-mysql-test.rb # # executing… # [{"sleep(1)"=>"0"}] em-mysqlplus: example asyncMySQL driver
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
httpA=EventMachine::HttpRequest.new(URL).get httpA.errback { # retry logic? } httpA.callback { Memcached.set(:key => URL, :value => httpA.response) { |response| caseresponse[:status] whenMemcached::Errors::NO_ERROR # That's good whenMemcached::Errors::DISCONNECTED # Maybe stop filling the cache for now? else # What could've gone wrong? end   } } http =get(url) memc=save(url, http.response) ifmemc.error? # That's good else # Err? end accidental complexity async is harder to manage
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
remcached: .get, etc, and .multi_* methods are synchronousem-synchrony: simple evented programming best of both worlds…
EventMachine.synchronydo     multi =EventMachine::Synchrony::Multi.new multi.add:a, EventMachine::HttpRequest.new(url1).aget multi.add:b, EventMachine::HttpRequest.new(url2).apost     res =multi.perform p“No callbacks, and parallel HTTP requests!" p res EventMachine.stop end Parallel IO with Fibers multi interface example
Persistent connections EventMachine.synchronydo     db =EventMachine::Synchrony::ConnectionPool.new(size:2) do EventMachine::MySQL.new(host:"localhost") end     multi =EventMachine::Synchrony::Multi.new multi.add:a, db.aquery("select sleep(1)") multi.add:b, db.aquery("select sleep(1)")     res =multi.perform EventMachine.stop end Fiber Pools accessing shared services
EM.synchronydo     concurrency =2 urls= ['http://url.1.com', 'http://url2.com']     results =EM::Synchrony::Iterator.new(urls, concurrency).mapdo |url, iter|         http =EventMachine::HttpRequest.new(url).aget http.callback { iter.return(http) } end p results # all completed requests EventMachine.stop end Explicit iterators .each, .map, .inject, … asynchronous iterators
EM.synchronydo   result =EM::Synchrony.syncEventMachine::HttpRequest.new(URL).get presult EM.stop end Inline synchronization Inline synchronization ad-hoc synchronization
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
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
Async web-stack in Ruby?

More Related Content

What's hot

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
 
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversTatsuhiko Miyagawa
 
Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Tatsuhiko Miyagawa
 
Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011leo lapworth
 
Web frameworks don't matter
Web frameworks don't matterWeb frameworks don't matter
Web frameworks don't matterTomas Doran
 
Event Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya GrigorikEvent Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya GrigorikIlya Grigorik
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)True-Vision
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
A complete guide to Node.js
A complete guide to Node.jsA complete guide to Node.js
A complete guide to Node.jsPrabin Silwal
 
Ruby in the Browser - RubyConf 2011
Ruby in the Browser - RubyConf 2011Ruby in the Browser - RubyConf 2011
Ruby in the Browser - RubyConf 2011Ilya Grigorik
 
Real Time Event Dispatcher
Real Time Event DispatcherReal Time Event Dispatcher
Real Time Event DispatcherPeter Dietrich
 
Building real time applications with Symfony2
Building real time applications with Symfony2Building real time applications with Symfony2
Building real time applications with Symfony2Antonio Peric-Mazar
 
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...Alexander Lisachenko
 
Asterisk, HTML5 and NodeJS; a world of endless possibilities
Asterisk, HTML5 and NodeJS; a world of endless possibilitiesAsterisk, HTML5 and NodeJS; a world of endless possibilities
Asterisk, HTML5 and NodeJS; a world of endless possibilitiesDan Jenkins
 

What's hot (20)

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
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
 
Plack at OSCON 2010
Plack at OSCON 2010Plack at OSCON 2010
Plack at OSCON 2010
 
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
 
Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011
 
Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
 
Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011
 
Web frameworks don't matter
Web frameworks don't matterWeb frameworks don't matter
Web frameworks don't matter
 
PSGI/Plack OSDC.TW
PSGI/Plack OSDC.TWPSGI/Plack OSDC.TW
PSGI/Plack OSDC.TW
 
Event Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya GrigorikEvent Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya Grigorik
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)
 
Tatsumaki
TatsumakiTatsumaki
Tatsumaki
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
A complete guide to Node.js
A complete guide to Node.jsA complete guide to Node.js
A complete guide to Node.js
 
Ruby in the Browser - RubyConf 2011
Ruby in the Browser - RubyConf 2011Ruby in the Browser - RubyConf 2011
Ruby in the Browser - RubyConf 2011
 
Real Time Event Dispatcher
Real Time Event DispatcherReal Time Event Dispatcher
Real Time Event Dispatcher
 
Building real time applications with Symfony2
Building real time applications with Symfony2Building real time applications with Symfony2
Building real time applications with Symfony2
 
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
 
Asterisk, HTML5 and NodeJS; a world of endless possibilities
Asterisk, HTML5 and NodeJS; a world of endless possibilitiesAsterisk, HTML5 and NodeJS; a world of endless possibilities
Asterisk, HTML5 and NodeJS; a world of endless possibilities
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 

Similar to No callbacks, No Threads - Cooperative web servers in Ruby 1.9

Ruby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay ShanghaiRuby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay ShanghaiJackson Tian
 
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
 
Evented Ruby VS Node.js
Evented Ruby VS Node.jsEvented Ruby VS Node.js
Evented Ruby VS Node.jsNitin Gupta
 
mri ruby gil
mri ruby gilmri ruby gil
mri ruby gilachempion
 
Node js presentation
Node js presentationNode js presentation
Node js presentationmartincabrera
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
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
 
Introduction to node.js GDD
Introduction to node.js GDDIntroduction to node.js GDD
Introduction to node.js GDDSudar Muthu
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.jsorkaplan
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.jsJack Franklin
 
Async programming and python
Async programming and pythonAsync programming and python
Async programming and pythonChetan Giridhar
 
Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Dinh Pham
 
TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011Lance Ball
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tourcacois
 
Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Visual Engineering
 

Similar to No callbacks, No Threads - Cooperative web servers in Ruby 1.9 (20)

Ruby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay ShanghaiRuby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay Shanghai
 
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
 
Concurrency in ruby
Concurrency in rubyConcurrency in ruby
Concurrency in ruby
 
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
 
Evented Ruby VS Node.js
Evented Ruby VS Node.jsEvented Ruby VS Node.js
Evented Ruby VS Node.js
 
mri ruby gil
mri ruby gilmri ruby gil
mri ruby gil
 
Node js presentation
Node js presentationNode js presentation
Node js presentation
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
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
 
Introduction to node.js GDD
Introduction to node.js GDDIntroduction to node.js GDD
Introduction to node.js GDD
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.js
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Introduction to Node.JS
Introduction to Node.JSIntroduction to Node.JS
Introduction to Node.JS
 
Async programming and python
Async programming and pythonAsync programming and python
Async programming and python
 
Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?
 
TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tour
 
Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.
 

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
 
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
 
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
 
Building Mini Google in Ruby
Building Mini Google in RubyBuilding Mini Google in Ruby
Building Mini Google in RubyIlya Grigorik
 
Taming The RSS Beast
Taming The  RSS  BeastTaming The  RSS  Beast
Taming The RSS BeastIlya Grigorik
 

More from Ilya Grigorik (9)

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
 
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
 
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
 
Building Mini Google in Ruby
Building Mini Google in RubyBuilding Mini Google in Ruby
Building Mini Google in Ruby
 
Taming The RSS Beast
Taming The  RSS  BeastTaming The  RSS  Beast
Taming The RSS Beast
 

Recently uploaded

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 

Recently uploaded (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 

No callbacks, No Threads - Cooperative web servers in Ruby 1.9

  • 1. No Callbacks, No Threads & Ruby 1.9 async & co-operative web-servers Ilya Grigorik @igrigorik
  • 2. Reactor Pattern Review: State of the art Async Primitives Callbacks & Fibers Async Rails?
  • 3. 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…
  • 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 } 5 shared connections # time ruby activerecord-pool.rb # # real 0m10.663s # user 0m0.405s # sys 0m0.201s
  • 5.
  • 6. BHP % power loss WHP
  • 7.
  • 8.
  • 9.
  • 10. Mongo Couch MySQL PSQL … Drivers Threads Ruby VM GIL Fibers … Network Mongrel Unicorn Passenger …
  • 11. 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
  • 12. 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
  • 13. Concurrency is a myth in Ruby still no parallelism in Ruby 1.9 http://bit.ly/ruby-gil
  • 14. 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…
  • 15. Drivers Ruby VM Network WEBRick Mongrel made Rails viable still powers a lot of Rails apps today
  • 16. Rails rediscovers Apache the worker/forker model…
  • 17. *nix IPC is fast! … Full Ruby VM An exclusive Ruby VM for EACH request am I the only one who thinks this is terrible?
  • 18. “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?
  • 19.
  • 20. …?
  • 21. Node imposes the full-stack requirements Node imposes async drivers Node imposes async frameworks *Surprise*: Node is “fast”
  • 22. = I’ll take Ruby over JS gem install eventmachine
  • 23. p "Starting"EM.rundop"Running in EM reactor"endp”won’t get here" whiletruedo timersnetwork_ioother_io end EventMachine Reactor concurrency without thread
  • 24. 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 callback fired 1s after “executing” # > ruby em-mysql-test.rb # # executing… # [{"sleep(1)"=>"0"}] em-mysqlplus: example asyncMySQL driver
  • 25. 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
  • 26. httpA=EventMachine::HttpRequest.new(URL).get httpA.errback { # retry logic? } httpA.callback { Memcached.set(:key => URL, :value => httpA.response) { |response| caseresponse[:status] whenMemcached::Errors::NO_ERROR # That's good whenMemcached::Errors::DISCONNECTED # Maybe stop filling the cache for now? else # What could've gone wrong? end } } http =get(url) memc=save(url, http.response) ifmemc.error? # That's good else # Err? end accidental complexity async is harder to manage
  • 27. and this callback goes to…
  • 28. We can do better than node.js all the benefits of evented code without the drawbacks
  • 29. 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
  • 30. 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
  • 31. 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
  • 32. 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
  • 33. 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
  • 34. 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
  • 35.
  • 36. Multi request interface which accepts any callback enabled client
  • 37. Fibered iterator to allow concurrency control & mixing of sync / async
  • 38. em-http-request: .get, etc are synchronous, while .aget, etc are async
  • 39. em-mysqlplus: .query is synchronous, while .aquery is async
  • 40. remcached: .get, etc, and .multi_* methods are synchronousem-synchrony: simple evented programming best of both worlds…
  • 41. EventMachine.synchronydo multi =EventMachine::Synchrony::Multi.new multi.add:a, EventMachine::HttpRequest.new(url1).aget multi.add:b, EventMachine::HttpRequest.new(url2).apost res =multi.perform p“No callbacks, and parallel HTTP requests!" p res EventMachine.stop end Parallel IO with Fibers multi interface example
  • 42. Persistent connections EventMachine.synchronydo db =EventMachine::Synchrony::ConnectionPool.new(size:2) do EventMachine::MySQL.new(host:"localhost") end multi =EventMachine::Synchrony::Multi.new multi.add:a, db.aquery("select sleep(1)") multi.add:b, db.aquery("select sleep(1)") res =multi.perform EventMachine.stop end Fiber Pools accessing shared services
  • 43. EM.synchronydo concurrency =2 urls= ['http://url.1.com', 'http://url2.com'] results =EM::Synchrony::Iterator.new(urls, concurrency).mapdo |url, iter| http =EventMachine::HttpRequest.new(url).aget http.callback { iter.return(http) } end p results # all completed requests EventMachine.stop end Explicit iterators .each, .map, .inject, … asynchronous iterators
  • 44. EM.synchronydo result =EM::Synchrony.syncEventMachine::HttpRequest.new(URL).get presult EM.stop end Inline synchronization Inline synchronization ad-hoc synchronization
  • 45. 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
  • 46. 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
  • 48. em-synchrony, connection pool, iterators… Drivers async-rack Ruby VM Fibers Network Thin http://code.macournoyer.com/thin/ One VM, full concurrency, network-bound Ruby 1.9, Fibers, Thin: in production!
  • 49. git clonegit://github.com/igrigorik/async-rails.git 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! AsyncRails 3 with EventMachine & MySQL thin –D start
  • 50. 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) Async DB! Async Rails with EventMachine & MySQL
  • 51. http://gist.github.com/445603 concurrency time 75 73.426 60 66.411 50 65.502 40 78.105 30 106.624 Async Rails with EventMachine & MySQL
  • 52. Async Rails 3 demo: http://github.com/igrigorik/async-rails/ 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?