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

(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
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
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
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
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Fact vs. Fiction: Autodetecting Hallucinations in LLMs
Fact vs. Fiction: Autodetecting Hallucinations in LLMsFact vs. Fiction: Autodetecting Hallucinations in LLMs
Fact vs. Fiction: Autodetecting Hallucinations in LLMsZilliz
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
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
 
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
 
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
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
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
 

Recently uploaded (20)

(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
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
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
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
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Fact vs. Fiction: Autodetecting Hallucinations in LLMs
Fact vs. Fiction: Autodetecting Hallucinations in LLMsFact vs. Fiction: Autodetecting Hallucinations in LLMs
Fact vs. Fiction: Autodetecting Hallucinations in LLMs
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
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
 
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
 
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
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
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.
 

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?