Concurrency in RubyMarco Borromeo - @borrosItalian Ruby Day - Milan - 15 June 2012
Concurrency - Why?Fill up all those cores!
Concurrency - Why?Fill up all those cores!Ruby is slow - Just add some more mongrels there
Concurrency - Why?Fill up all those cores!Ruby is slow - Just add some more mongrels there
How to achieve concurrencyMultiple processes / forkingThreadsFibers
Multiple processes / forking Most commonly used solution to gain concurrency in Ruby
Multiple processes / forking Most commonly used solution to gain concurrency in Ruby No shared states between running proc...
Multiple processes / forking Most commonly used solution to gain concurrency in Ruby No shared states between running proc...
Multiple processes / forking Most commonly used solution to gain concurrency in Ruby No shared states between running proc...
Multiple processes / forking Most commonly used solution to gain concurrency in Ruby No shared states between running proc...
Multiple processes / forking LOT of memory used! 5 Rails apps is something like 45MB * 5 = 255MB! Unix copy-on-write (CoW)...
Multiple processes / forkingRuby Garbage Collector (GC) will write to every object every timeit will run, so the whole pro...
Multiple processes / forking Passenger fixed the copy-on-write issues creating a CoW- friendly GC, and it will be integrate...
Multiple processes / forking Passenger fixed the copy-on-write issues creating a CoW- friendly GC, and it will be integrate...
How to achieve concurrencyMultiple processes / forkingThreadsFibers
ThreadsRuby 1.8 has "green threads". They are scheduled by the VM,and emulate multithreaded environments even if they are ...
ThreadsBoth 1.8 and 1.9 have the Global Interpreter Lock (GIL).Having GIL means that any time one thread is running Rubyco...
ThreadsRace conditions, dead locks, synchronizing...
ThreadsRace conditions, dead locks, synchronizing...
ThreadsRace conditions, dead locks, synchronizing...... JRuby manages threads very well, has no GIL and let youuse all you...
ThreadsRace conditions, dead locks, synchronizing...... JRuby manages threads very well, has no GIL and let youuse all you...
How to achieve concurrencyMultiple processes / forkingThreadsFibers
Fibers Natively available only in Ruby 1.9 They are like simplified threads, but they arent scheduled by the VM but by the ...
Fibers
FibersThey still suffer the GIL presence.
Recap
RecapForking
RecapForking GC prevents us to have a proper memory management
RecapForking GC prevents us to have a proper memory managementThreads
RecapForking GC prevents us to have a proper memory managementThreads Difficult to manage Difficult to debug in production G...
RecapForking GC prevents us to have a proper memory managementThreads Difficult to manage Difficult to debug in production G...
RecapForking GC prevents us to have a proper memory managementThreads Difficult to manage Difficult to debug in production G...
No Concurrency, sorry.
No Concurrency, sorry.
Blocking I/O               90% I/O          10% Code Execution
Reactor PatternApplication server (AS) receives a request from a browserAS queues the request in the ReactorReactor proces...
Reactor PatternApplication server (AS) receives a request from a browserAS queues the request in the ReactorReactor proces...
Reactor PatternApplication server (AS) receives a request from a browserAS queues the request in the ReactorReactor proces...
Reactor PatternOur app makes the http request to the third-party service, using an asynclibrary (em-http) and provides a c...
Reactor PatternEarlier HTTP API call returns (or fails!) and the callback is enqueued into theReactorControl returns to th...
Blocking I/O  Everything has the advantage of being concurrent          without having to be thread-safe.           It is ...
EventMachineIs the Ruby implementation of the Reactor Pattern ::DeferrableChildProcess - Wait for a process to exit ::File...
EventMachineIs the Ruby implementation of the Reactor Pattern ::Protocols::HttpClient      ::Protocols::SmtpServer ::Proto...
EventMachineIssues:   Not so very well documented   Difficult to adopt for "syncronous programmers"   Doesnt play well with...
EventMachine
EventMachineEventMachine.run {  page = EventMachine::HttpRequest.new(http://github.com/).get  page.errback { p "GitHub is ...
EM-Syncrony"Collection of convenience classes and primitives to help untangle evented  code, plus a number of patched EM c...
EM-Syncrony mysql2 activerecord      Other clients: em-http-request      em-redis em-memcached         hiredis em-mongo mo...
Sinatra::Synchrony EventMachine + EM-Syncrony Rack::FiberPool em-http-request em-resolv-replace Patches TCPSocket (via EM-...
Sinatra::Synchrony         gem install sinatra-synchrony          require sinatra/synchrony          register Sinatra::Syn...
Thanks!Marco Borromeo@borrosmarco@continuityapp.com
Upcoming SlideShare
Loading in …5
×

Concurrency in ruby

2,485
-1

Published on

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,485
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
17
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide
  • \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
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Concurrency in ruby

    1. 1. Concurrency in RubyMarco Borromeo - @borrosItalian Ruby Day - Milan - 15 June 2012
    2. 2. Concurrency - Why?Fill up all those cores!
    3. 3. Concurrency - Why?Fill up all those cores!Ruby is slow - Just add some more mongrels there
    4. 4. Concurrency - Why?Fill up all those cores!Ruby is slow - Just add some more mongrels there
    5. 5. How to achieve concurrencyMultiple processes / forkingThreadsFibers
    6. 6. Multiple processes / forking Most commonly used solution to gain concurrency in Ruby
    7. 7. Multiple processes / forking Most commonly used solution to gain concurrency in Ruby No shared states between running processes. You need to use DRb, a message bus like RabbitMQ
    8. 8. Multiple processes / forking Most commonly used solution to gain concurrency in Ruby No shared states between running processes. You need to use DRb, a message bus like RabbitMQ ... or some shared data store like MySQL
    9. 9. Multiple processes / forking Most commonly used solution to gain concurrency in Ruby No shared states between running processes. You need to use DRb, a message bus like RabbitMQ ... or some shared data store like MySQL
    10. 10. Multiple processes / forking Most commonly used solution to gain concurrency in Ruby No shared states between running processes. You need to use DRb, a message bus like RabbitMQ ... or some shared data store like MySQL Forked processses can read the state of the program before the fork, but updates wont be shared
    11. 11. Multiple processes / forking LOT of memory used! 5 Rails apps is something like 45MB * 5 = 255MB! Unix copy-on-write (CoW) comes to help: no need to copy the whole memory into the forked process, and only the data changed after the fork will be copied and modified. but...
    12. 12. Multiple processes / forkingRuby Garbage Collector (GC) will write to every object every timeit will run, so the whole process memory will be then copied.Basically, Ruby loses all the benefits of CoW.
    13. 13. Multiple processes / forking Passenger fixed the copy-on-write issues creating a CoW- friendly GC, and it will be integrated into Ruby 2.0
    14. 14. Multiple processes / forking Passenger fixed the copy-on-write issues creating a CoW- friendly GC, and it will be integrated into Ruby 2.0 Rubinius is CoW friendly
    15. 15. How to achieve concurrencyMultiple processes / forkingThreadsFibers
    16. 16. ThreadsRuby 1.8 has "green threads". They are scheduled by the VM,and emulate multithreaded environments even if they are not.Ruby 1.9 has OS threads.Preemptive scheduling
    17. 17. ThreadsBoth 1.8 and 1.9 have the Global Interpreter Lock (GIL).Having GIL means that any time one thread is running Rubycode, no other thread can be running Ruby code.Even if you have multiple threads, you can only use at most 1core of your CPU at a time.
    18. 18. ThreadsRace conditions, dead locks, synchronizing...
    19. 19. ThreadsRace conditions, dead locks, synchronizing...
    20. 20. ThreadsRace conditions, dead locks, synchronizing...... JRuby manages threads very well, has no GIL and let youuse all your cores.
    21. 21. ThreadsRace conditions, dead locks, synchronizing...... JRuby manages threads very well, has no GIL and let youuse all your cores.Rubinius is working on removing GIL
    22. 22. How to achieve concurrencyMultiple processes / forkingThreadsFibers
    23. 23. Fibers Natively available only in Ruby 1.9 They are like simplified threads, but they arent scheduled by the VM but by the programmer Faster than threads, and use less memory
    24. 24. Fibers
    25. 25. FibersThey still suffer the GIL presence.
    26. 26. Recap
    27. 27. RecapForking
    28. 28. RecapForking GC prevents us to have a proper memory management
    29. 29. RecapForking GC prevents us to have a proper memory managementThreads
    30. 30. RecapForking GC prevents us to have a proper memory managementThreads Difficult to manage Difficult to debug in production GIL prevents us to have concurrency
    31. 31. RecapForking GC prevents us to have a proper memory managementThreads Difficult to manage Difficult to debug in production GIL prevents us to have concurrencyFibers
    32. 32. RecapForking GC prevents us to have a proper memory managementThreads Difficult to manage Difficult to debug in production GIL prevents us to have concurrencyFibers Difficult to debug in production GIL prevents us to have concurrency
    33. 33. No Concurrency, sorry.
    34. 34. No Concurrency, sorry.
    35. 35. Blocking I/O 90% I/O 10% Code Execution
    36. 36. Reactor PatternApplication server (AS) receives a request from a browserAS queues the request in the ReactorReactor process the request, passing the control to our AppIn order to process the request, our app needs to perform some APIqueries over third-party services
    37. 37. Reactor PatternApplication server (AS) receives a request from a browserAS queues the request in the ReactorReactor process the request, passing the control to our AppIn order to process the request, our app needs to perform some APIqueries over third-party services ...zZzZzzZzZzZ...
    38. 38. Reactor PatternApplication server (AS) receives a request from a browserAS queues the request in the ReactorReactor process the request, passing the control to our AppIn order to process the request, our app needs to perform some APIqueries over third-party services ...zZzZzzZzZzZ...
    39. 39. Reactor PatternOur app makes the http request to the third-party service, using an asynclibrary (em-http) and provides a callback to be executed when a reply isreceivedControl returns to the ReactorReactor pulls the next event from the queue and executes it
    40. 40. Reactor PatternEarlier HTTP API call returns (or fails!) and the callback is enqueued into theReactorControl returns to the ReactorReactor starts executing the callback which processes the results of the APIrequest, builds a response and sends it to the browser.Done
    41. 41. Blocking I/O Everything has the advantage of being concurrent without having to be thread-safe. It is a "cooperative multitasking" (while Threads have a “Preemptive scheduling“ approach)
    42. 42. EventMachineIs the Ruby implementation of the Reactor Pattern ::DeferrableChildProcess - Wait for a process to exit ::FileStreamer - Streams a file over a connection ::FileWatch - Monitors a file, get notified when it gets deleted, modified or moved ::PeriodicTimer - Executes something every interval seconds
    43. 43. EventMachineIs the Ruby implementation of the Reactor Pattern ::Protocols::HttpClient ::Protocols::SmtpServer ::Protocols::Memcache ::Protocols::Socks4 ::Protocols::Postgres3 ::Protocols::Stomp ::Protocols::SmtpClient
    44. 44. EventMachineIssues: Not so very well documented Difficult to adopt for "syncronous programmers" Doesnt play well with actual web frameworks
    45. 45. EventMachine
    46. 46. EventMachineEventMachine.run { page = EventMachine::HttpRequest.new(http://github.com/).get page.errback { p "GitHub is Down. Everybody run for your life!" } page.callback { about = EventMachine::HttpRequest.new(http://github.com/api/v2/json/repos/show/schacon).get about.callback { } about.errback { } }}
    47. 47. EM-Syncrony"Collection of convenience classes and primitives to help untangle evented code, plus a number of patched EM clients to make them Fiber aware." EventMachine.synchrony do homepage = EventMachine::HttpRequest.new("http://github.com/").get apiResponse = EventMachine::HttpRequest.new("http://github.com/api/v2/ json/repos/show/schacon").get p "No callbacks! Fetched API: #{apiResponse}" EventMachine.stop end
    48. 48. EM-Syncrony mysql2 activerecord Other clients: em-http-request em-redis em-memcached hiredis em-mongo mongoid AMQP
    49. 49. Sinatra::Synchrony EventMachine + EM-Syncrony Rack::FiberPool em-http-request em-resolv-replace Patches TCPSocket (via EM-Syncrony) (!) Patches Rack::Test
    50. 50. Sinatra::Synchrony gem install sinatra-synchrony require sinatra/synchrony register Sinatra::Synchrony
    51. 51. Thanks!Marco Borromeo@borrosmarco@continuityapp.com
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×