Ruby Concurrency




Slides & links posted to
Goal = Efficiency
At the Expense of
What Is Inefficient?




   CPU Idling While You
What Is Inefficient?




   Not Using All of Your
Types of Ruby
•Processes
•Threads
•Actors
•Fibers
•Events
Completely




             Hadoop
Completely




             Hadoop
Forked Processes
              http://tomayko.com/writings/unicorn-is-unix




      Ruby subprocess
Forked Processes
              http://tomayko.com/writings/unicorn-is-unix




      Ruby subprocess
forkoff gem
Many Ways to Start




system, exec, IO.popen,
Complex Fork




       Spork, Unicorn,
Copy-on-Write




   Rubinius, Enterprise
Copy-on-Write




   Rubinius, Enterprise
Process Concurrency

•Simple
•Easy to debug
Process Concurrency

•Requires you to start/monitor each process
•Requires some type of RPC (dRb, Resque, etc)
•Can’t share resources (like connection pools)
•Memory inefficient w/o copy-on-write
•One process per core
Thread Concurrency




    http://blog.carbonfive.com/2011/10/11/a-modern-guide-to-threads/




  Concurrency within a
Thread Concurrency




    http://blog.carbonfive.com/2011/10/11/a-modern-guide-to-threads/




  Concurrency within a
Concurrent vs Parallel
Concurrent vs Parallel
Simple Thread Example
Complex Thread




             Mongrel
Green Threads

•VM-managed
•Lightweight
•1 per core
•Blocking I/O blocks all threads
Native Threads

•Scheduled by OS
•Do not block other threads during I/O
•Can run on multiple cores*
*Global Interpreter Lock

•Only allows one thread to run at a time
•Ruby C code not threadsafe
•Released during I/O
Released During I/O




          http://yehudakatz.com/2010/08/14/threads-in-ruby-enough-already/
Rubies without GIL




            http://www.engineyard.com/blog/2011/ruby-concurrency-and-you/
Thread Safety




           http://blog.carbonfive.com/2011/10/11/a-modern-guide-to-threads/
Thread Safety




           http://blog.carbonfive.com/2011/10/11/a-modern-guide-to-threads/
Thread Safety
          ruby thread.rb = 200000

          jruby thread.rb = 1067198




            http://blog.carbonfive.com/2011/10/11/a-modern-guide-to-threads/
Thread Safety
Thread Safety




   Queue, SizedQueue,
Thread Pros

•More intuitive than fibers/events
•Sans GIL: most efficient/performant* technique
•Single process to monitor
•Shared resources, no RPC
•Fine-grained control of thread lifecycle



                 *http://teddziuba.com/2011/10/straight-talk-on-event-loops.html
Thread Cons

•Increased complexity (vs processes)
•Notoriously hard to debug
•Potential for deadlocks and race conditions




                                        Text
Actor Concurrency




   Message passing vs.
Actor Concurrency




   Message passing vs.
Actor Concurrency




    “Threads that don’t
Actor Concurrency




               http://mperham.github.com/girl_friday/




            girl_friday
Where You Can Get


•JRuby and Rubinius Actor API
•celluloid gem




                                Text
Fiber Concurrency




    Manually scheduled
Fiber Concurrency

•Code blocks that can be paused/resumed
•Lighter than threads, cannot be preempted
•Scheduled by programmer
•Can share data without mutexes



        Manually scheduled
Simple Fiber Example




             http://paulbarry.com/articles/2010/04/01/fibers-in-ruby-1-9
Complex Fiber Example




Goliath, em-synchrony,
Complex Fiber Example




Goliath, em-synchrony,
Fiber Pros

•Much lighter memory use than threads
•Faster to start vs threads
•Can share data without mutex
•Can simplify asynchronous APIs (em-synchrony)



                                      Text
Fiber Cons

•Limited to one CPU core
•Nonintuitive
•Syntax can get confusing
•Need to use fiber-aware libraries for I/O



                                        Text
Event Concurrency




      Single-thread w/
Event Concurrency




      Single-thread w/
EM::WebSocket
EventMachine Pros

•Performs well under heavy network I/O
•Zero overhead
•Can still use threads via EM.defer
EventMachine Cons

•Inversion of control can be confusing
•Hard to test
•Nested callbacks can lead to spaghetti code
•Threads can still beat events (all apps will
eventually become CPU bound)
General Advice: MRI



  Threads/Actors
                      Threads/Actors
       Events                           Threads/Actors
                      Forks/Processes
 Fibers (synchrony)
General Advice: JRuby/



 Threads/Actors
                  Threads/Actors   Threads/Actors
     Events
Links on subelsky.com



  Questions?

            @subelsky

Ruby Concurrency Realities