Fast, concurrent ruby web applications with EventMachine and EM::Synchrony
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Fast, concurrent ruby web applications with EventMachine and EM::Synchrony

on

  • 19,925 views

 

Statistics

Views

Total Views
19,925
Views on SlideShare
19,803
Embed Views
122

Actions

Likes
32
Downloads
160
Comments
4

10 Embeds 122

http://paper.li 51
http://twitter.com 34
https://twitter.com 18
http://us-w1.rockmelt.com 8
http://tweetedtimes.com 4
http://www.linkedin.com 2
https://www.linkedin.com 2
http://www.slideshare.net 1
http://www.techgig.com 1
http://www.twylah.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Fast, concurrent ruby web applications with EventMachine and EM::Synchrony Presentation Transcript

  • 1. Fast, concurrent rubyweb applications withEM and EM::Synchrony Kyle Drake
  • 2. A bit about me.• Full time Facebook developer• All FB apps: Sinatra + DM, MRI + Thin on EY, Heroku• Lots and lots of slow API calls to Facebook• Lots and lots of delayed timeouts, API errors• Lots and lots of users• Lots and lots of performance issues from slow API calls!
  • 3. MapAttack!
  • 4. MapAttack!• Over 60 hits per second• Lots of network API calls to Geoloqi platform• Lots of scary thread exceptions (Rainbows! + ThreadSpawn)• Completely unsustainable as a conventional ruby web application
  • 5. What’s going on here?• Blocking IO!• Process spends 90% of time waiting, 10% actually doing something• Raw performance (Typheous vs Net::HTTP) is almost irrelevant! It’s not your bottleneck.• MRI: No real threads, so IO blocks. 1.8 has green threads, 1.9 has kernel threads with GIL• JRuby: Real kernel threads, much better. But slow (before JIT warms up), special deploy stack, and...
  • 6. Based on the Reactor pattern.. No threads (sortof) No blocking IO at all Uses callbacks as events var app = express.createServer(); app.get(/, function(req, res){ res.send(Hello World); }); app.listen(3000);Is this the future of web development?
  • 7. CALLBACK HELLvar useFile = function(filename,callback){    posix.stat(filename).addCallback(function (stats) {        posix.open(filename, process.O_RDONLY, 0666).addCallback(function (fd) {            posix.read(fd, stats.size, 0).addCallback(function(contents){                callback(contents);            });        });    });}; I found far worse examples, but they wouldn’t fit on this page.
  • 8. New feature: Joyent Owns It “Any sort of use in commerce, such as promoting a Platform-as-a-Service or professional services offering by using the Node.js mark, does require a written license agreement.”“If Joyent notifies you that your use of any trademark is detrimental to any Joyent trademarks or isotherwise unacceptable, you must immediately cease using the marks, blah blah...”
  • 9. What does Node.js do?It uses the Reactor pattern. Can we copy it? YES!
  • 10. The Reactor Pattern “The reactor design pattern is a concurrent programming pattern for handling service requests delivered concurrently to a service handler by one or more inputs” - Wikipedia What Node.js does: Takes your blocking IO operation, shoves it into its own kernel threadbehind the scenes, uses Unix kernel magic to make it rejoin the reactor queue when it’s ready. • Linux: epoll(4) • BSD: kqueue/kevent
  • 11. • Blocking IO a UNIVERSAL problem• All programming languages have trouble with it• The Reactor pattern resolves it• Most languages have the Reactor pattern!
  • 12. • Blocking IO a UNIVERSAL problem• All programming languages have trouble with it• The Reactor pattern resolves it• Most languages have the Reactor pattern! JavaScript Node.js Python Twisted Ruby EventMachine (libem, C) Java JBoss_Netty (wait, what? I thought Java had good threading..) PHP None yet (perhaps ever)
  • 13. EventMachine • Stable, fast, mature, works! • Production tested • Thin has EM built in • Hosting Support (CloudFoundry, Heroku)# Source: http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/EventMachine.run { page = EventMachine::HttpRequest.new(http://google.ca/).get page.errback { p "Google is down! terminate?" } page.callback { about = EventMachine::HttpRequest.new(http://google.ca/search?q=eventmachine).get about.callback { # callback nesting, ad infinitum } about.errback { # error-handling code } }}
  • 14. EventMachine The Bad• Documentation is weak• It’s weird for synchronous programmers• Education problem - nobody understands it• Like Node.js, it requires callback programming• Callbacks don’t play nicely with web frameworks without nasty hacks (async-sinatra, throw :async, et cetera)
  • 15. EventMachineWhat if I told you you could do concurrent asynchronous programming, WITHOUT CALLBACKS?
  • 16. EM-Synchrony• http://github.com/igrigorik/em-synchrony• “Collection of convenience classes and primitives to help untangle evented code, plus a number of patched EM clients to make them Fiber aware”• Wraps callbacks in Ruby 1.9 Fibers automatically via EM::Synchrony.sync. The result: NO CALLBACKS!• Anything with a callback method can be patched instantly to support this.
  • 17. EM-Synchronydef http_get(url) f = Fiber.current http = EventMachine::HttpRequest.new(url).get # resume fiber once http call is done http.callback { f.resume(http) } http.errback { f.resume(http) } return Fiber.yieldendEventMachine.run do Fiber.new{ page = http_get(http://www.google.com/) puts "Fetched page: #{page.response_header.status}" if page page = http_get(http://www.google.com/search?q=eventmachine) puts "Fetched page 2: #{page.response_header.status}" end }.resumeend
  • 18. EM-SynchronyEventMachine.synchrony do page = EventMachine::HttpRequest.new("http://www.google.com").get p "No callbacks! Fetched page: #{page}" EventMachine.stopend
  • 19. EM-Synchrony Goliath http://postrank-labs.github.com/goliathrequire goliathclass Hello < Goliath::API # reload code on every request in dev environment use ::Rack::Reloader, 0 if Goliath.dev? def response(env) [200, {}, "Hello World"] endend# > ruby hello.rb -sv# > [97570:INFO] 2011-02-15 00:33:51 :: Starting server on 0.0.0.0:9000
  • 20. EM-Synchrony Goliath• Awesome! But...• Designed for SOA work, not high-level web development• Doesn’t play nicely with Rack, Thin, Heroku• It’s re-inventing the wheel (I love Sinatra!)• Can we make Sinatra work with EM-Synchrony? YES!
  • 21. Sinatra-Synchrony http://github.com/kyledrake/sinatra-synchrony• Tiny glue extension, < 100 LOC• Same old Sinatra, concurrency is (mostly) built in.• EventMachine and EM-Synchrony, Rack, Thin, Rainbows!, CloudFoundry, Heroku• Wraps each request in its own Fiber• Only coding change is to use non-blocking drivers/libraries• Patches Rack::Test to make tests run within EM-Synchrony fiber Wow, that was easy.
  • 22. Conclusions• You can bake strong concurrency support into Ruby with almost zero changes to your code• You can take advantage of this while programming synchronously as usual.. Node.js can’t!• This makes Ruby a real competitor here. Strong performance, concurrency, maintainability, productivity, testing• RUBY IS NOT SLOW. This is a marketing failure, and we need to fix it.
  • 23. What You Can Do• Try this stuff out! Play with it. Teach others how to use it. Work on the code for it.• Help me with this Sinatra-Synchrony idea. Perhaps we can make the idea more general purpose? Rails support?• DEFEND RUBY FROM THE “RUBY IS SLOW” PEOPLE. Sinatra-Synchrony gets 3000 hits per second in benchmarks on my MacBook with OSX’s crappy network stack, on one core. Productivity and performance are not incompatible here.• It’s my birthday today, get me drunk.
  • 24. The Future Rubinius - Hydra Branch http://rubini.us/2011/02/17/rubinius-what-s-next• The Smalltalk-80 Blue Book approach is working• They are trashing their GIL with pure ruby!• Supports EventMachine, Fibers coming soon• Because of Evan (and friends), Alan Kay, Ezra, RUBINIUS IS THE FUTURE
  • 25. Thank you.Questions?