SlideShare a Scribd company logo
Ruby Concurrency
...and the mysterious case of the Reactor Pattern




                                       Christopher Spring
or...
WTF the EventMachine
and why should I care?
WTF the EventMachine
and why should I care?
WTF the EventMachine
and why should I care?
Resource utilization

                      • Lots of IO (90/10)
                       • Disk
                       • Network
                       • system()
                      • Lots of cores

http://www.mikeperham.com/2010/01/27/scalable-ruby-processing-with-eventmachine/
Ruby concurrency basics

      • Threads
      • Fibers
      • Processes
Threading Models
       1: N


       1 :1


      M :N
Threading Models
                 1: N


Kernel Threads   1 :1   User Threads


                 M :N
Threading Models
                 1: N


                 1 :1


                 M :N



Kernel Threads           User Threads
Threading Models
                    1: N
  • Green Threads
  • Ruby 1.8        1 :1

  • Pros/Cons
                    M :N



Kernel Threads             User Threads
Threading Models
                 1: N


                 1 :1


                 M :N



Kernel Threads           User Threads
Threading Models
                       1: N
  • Native Threads
  • Ruby 1.9 / jRuby   1 :1

  • Pros/Cons
                       M :N



Kernel Threads                User Threads
Threading Models
                 1: N


                 1 :1   ?
                 M :N



Kernel Threads           User Threads
Threads
Threads

• Shared state and memory space
Threads

• Shared state and memory space
• Relatively light weight
Threads

• Shared state and memory space
• Relatively light weight
• Preemptive scheduling
Ruby Concurrency and EventMachine
Ruby has baggage: GIL




 http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/
Threads... suck
Threads... suck

• Race conditions
Threads... suck

• Race conditions
• Deadlocks
Threads... suck

• Race conditions
• Deadlocks
• Hard to debug
Threads... suck

• Race conditions
• Deadlocks
• Hard to debug
• GIL
Threads... suck

• Race conditions
• Deadlocks
• Hard to debug
• GIL
Fibers
Fibers

• It’s a coroutine, dammit!
Fibers

• It’s a coroutine, dammit!
 • “... [component to] generalize
    subroutines to allow multiple entry
    points for suspending and resuming
    execution at certain locations.”
file_iterator = Fiber.new do
  file = File.open('stuff.csv', 'r')
  while line = file.gets
    Fiber.yield line
  end
  file.close
end

3.times{ file_iterator.resume }

# => line 1
# => line 2
# => line 3
Fibers

• Cooperative Scheduling
• Very lightweight
• Maintains state
• Great for: cooperative tasks, iterators,
  infinite lists and pipes
def interpret_csv( csv_source )
  Fiber.new do
    while csv_source.alive?
      str = csv_source.resume
      Fiber.yield str.split(',').map(&:strip)
    end
  end
end

def file_iterator(file_name)
  Fiber.new do
    file = File.open(file_name, 'r')
    while line = file.gets
      Fiber.yield line
    end
    file.close
  end
end

interpret_csv( file_iterator('stuff.csv') ).resume

# => [...]
Reactor Pattern
Client     Client    Client     Client




                     IO Stream




Event Handler A     Event Dispatcher
Event Handler B
                                        Demultiplexer
Event Handler C
Event Handler D
Benefits

• Non blocking IO
• Coarse grain concurrency
• No threads!
• Single Process
Limitations

• Hard to debug
• Dispatch to event handlers is synchronous
• Demultiplexer polling limits
EventMachine
require 'eventmachine'

class EchoServer < EM::Connection
  def post_init
    puts "New connecting"
  end

  def unbind
    puts "Connection closed"
  end

  def receive_data(data) # unbuffered!!
    puts "<< #{data}"
    send_data ">> #{data}"
  end
end

EM.run do
  EM.start_server('127.0.0.1', 9000, EchoServer)
  puts "Started server at 127.0.0.1:9000"
end # Runs till EM.stop called
#   $ telnet localhost 9000
require 'eventmachine'                    #   Hello
                                          #   >> Hello
class EchoServer < EM::Connection         #   Bye
  def post_init                           #   >> Bye
    puts "New connecting"
  end

  def unbind
    puts "Connection closed"
  end

  def receive_data(data) # unbuffered!!
    puts "<< #{data}"
    send_data ">> #{data}"
  end
end

EM.run do
  EM.start_server('127.0.0.1', 9000, EchoServer)
  puts "Started server at 127.0.0.1:9000"
end # Runs till EM.stop called
Primitives

• run loop
• next_tick; add_timer; add_periodic_timer
• EM.defer
• EM::Queue
• EM::Channel
EM.run do
               Defer
  operation = Proc.new do
    puts 'MapMap!!'
    sleep 3
    puts 'Done collecting data'
    [1, 1, 2, 3, 5, 8, 13]
  end

  callback = Proc.new do |arr|
    puts 'Reducing...'
    sleep 1
    puts 'Reduced'
    puts arr.inject(:+)
    EM.stop
  end

  EM.defer(operation, callback)
end
EM.run do
               Defer              #
                                  #
                                  #
                                      MapMap!!
                                      Done collecting data
                                      Reducing...
                                  #   Reduced
  operation = Proc.new do
                                  #   33
    puts 'MapMap!!'
    sleep 3
    puts 'Done collecting data'
    [1, 1, 2, 3, 5, 8, 13]
  end

  callback = Proc.new do |arr|
    puts 'Reducing...'
    sleep 1
    puts 'Reduced'
    puts arr.inject(:+)
    EM.stop
  end

  EM.defer(operation, callback)
end
EM.run do
            Queue
  queue = EM::Queue.new

  EM.defer do
    sleep 2; queue.push 'Mail 1'
    sleep 3; queue.push 'Mail 2'
    sleep 4; queue.push 'Mail 3'
  end

  mail_sender = Proc.new do |mail|
    puts "Sending #{mail}"
    EM.next_tick{ queue.pop(&mail_sender)}
  end

  queue.pop(&mail_sender)

end
Channel
EM.run do
  channel = EM::Channel.new

 EM.defer do
   channel.subscribe do |msg|
     puts "Received #{msg}"
   end
 end

  EM.add_periodic_timer(1) do
    channel << Time.now
  end
end
class Mailer
  include EM::Deferrable    Deferrable
  def initialize
    callback do
      sleep 1
      puts 'Updated statistics!'
    end

    errback{ puts 'retrying mail'}
  end

  def send
    rand >= 0.5 ? succeed : fail
  end
end

EM.run do
  5.times do
    mailer = Mailer.new
    EM.add_timer(rand * 5){ mailer.send}
  end
end
class Mailer
  include EM::Deferrable    Deferrable
  def initialize                 # Updating statistics!
    callback do                  # Updating statistics!
      sleep 1                    # retrying mail
      puts 'Updated statistics!'
    end

    errback{ puts 'retrying mail'}
  end

  def send
    rand >= 0.5 ? succeed : fail
  end
end

EM.run do
  5.times do
    mailer = Mailer.new
    EM.add_timer(rand * 5){ mailer.send}
  end
end
class Mailer
               Stacked callbacks
  include EM::Deferrable

                              EM.run do
  def add_mailing(val)
                                m = Mailer.new
    callback{
                                m.add_mailing(1)
      sleep 1;
                                m.add_mailing(2)
      puts "Sent #{val}"
                                m.connection_open!
    }
  end
                                EM.add_timer(1) do
                                  m.connection_lost!
  def connection_open!
                                  EM.add_timer(2) do
    puts 'Open connection'
                                    m.add_mailing(3)
    succeed
                                    m.add_mailing(4)
  end
                                    m.connection_open!
                                  end
  def connection_lost!
                                end
    puts 'Lost connection'
                              end
    set_deferred_status nil
  end
end
class Mailer
               Stacked callbacks
  include EM::Deferrable

                              EM.run do
  def add_mailing(val)
                                m = Mailer.new
    callback{                                            #   Open   connection
                                m.add_mailing(1)
      sleep 1;
                                m.add_mailing(2)         #   Sent   1
      puts "Sent #{val}"
                                m.connection_open!       #   Sent   2
    }
  end                                                    #   Lost   connection
                                EM.add_timer(1) do
                                                         #   Open   connection
                                  m.connection_lost!
  def connection_open!                                   #   Sent   3
                                  EM.add_timer(2) do
    puts 'Open connection'
                                    m.add_mailing(3)     #   Sent   4
    succeed
                                    m.add_mailing(4)
  end
                                    m.connection_open!
                                  end
  def connection_lost!
                                end
    puts 'Lost connection'
                              end
    set_deferred_status nil
  end
end
Gotchas

• Synchronous code will slow it down
 • Use/Write libraries for EM
• Everything in the event loop must be async!
Summary

• It’s a blocking world!
• Alternative concurrency implementations
• Start playing with EM
Worth checking out

• EM-Synchrony:
  https://github.com/igrigorik/em-synchrony
• Goliath:
  https://github.com/postrank-labs/goliath
Ruby Concurrency and EventMachine
Baie Dankie!
Questions?
Links

• http://www.mikeperham.com
• http://www.igvita.com (!!)
• http://rubyeventmachine.com/

More Related Content

PDF
Scaling Ruby with Evented I/O - Ruby underground
KEY
EventMachine for RubyFuZa 2012
KEY
jRuby: The best of both worlds
PDF
Steady with ruby
PPTX
No Callbacks, No Threads - RailsConf 2010
PPTX
Ruby C10K: High Performance Networking - RubyKaigi '09
KEY
Streams are Awesome - (Node.js) TimesOpen Sep 2012
KEY
Servers with Event Machine - David Troy - RailsConf 2011
Scaling Ruby with Evented I/O - Ruby underground
EventMachine for RubyFuZa 2012
jRuby: The best of both worlds
Steady with ruby
No Callbacks, No Threads - RailsConf 2010
Ruby C10K: High Performance Networking - RubyKaigi '09
Streams are Awesome - (Node.js) TimesOpen Sep 2012
Servers with Event Machine - David Troy - RailsConf 2011

What's hot (20)

PDF
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
KEY
Message queueing
PDF
Implementações paralelas
PDF
Test driven infrastructure
PDF
Dataflow: Declarative concurrency in Ruby
PDF
Current State of Coroutines
PDF
When Ruby Meets Java - The Power of Torquebox
PDF
Erlang and Elixir
PPTX
Javascript asynchronous
PDF
Coroutines for Kotlin Multiplatform in Practise
PDF
Rapid web development using tornado web and mongodb
PDF
Follow the White Rabbit - Message Queues with PHP
PDF
Microarmy - by J2 Labs
KEY
Do more than one thing at the same time, the Python way
PDF
Introduction to kotlin coroutines
PDF
Node.js streaming csv downloads proxy
PDF
Tornado Web Server Internals
PDF
Introduction to orchestration using Mcollective
PPTX
Python, async web frameworks, and MongoDB
PDF
Javascript Promises/Q Library
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Message queueing
Implementações paralelas
Test driven infrastructure
Dataflow: Declarative concurrency in Ruby
Current State of Coroutines
When Ruby Meets Java - The Power of Torquebox
Erlang and Elixir
Javascript asynchronous
Coroutines for Kotlin Multiplatform in Practise
Rapid web development using tornado web and mongodb
Follow the White Rabbit - Message Queues with PHP
Microarmy - by J2 Labs
Do more than one thing at the same time, the Python way
Introduction to kotlin coroutines
Node.js streaming csv downloads proxy
Tornado Web Server Internals
Introduction to orchestration using Mcollective
Python, async web frameworks, and MongoDB
Javascript Promises/Q Library
Ad

Viewers also liked (8)

PDF
jRuby and TorqueBox
PDF
Ruby EventMachine + em-WebSocket
PDF
Event Machine
ODP
Le 10 principali ragioni per cui Ruby fa pena
PDF
Eventdriven I/O - A hands on introduction
PDF
Multi-threaded web crawler in Ruby
KEY
Actors and Threads
PDF
Scaling Apache Storm - Strata + Hadoop World 2014
jRuby and TorqueBox
Ruby EventMachine + em-WebSocket
Event Machine
Le 10 principali ragioni per cui Ruby fa pena
Eventdriven I/O - A hands on introduction
Multi-threaded web crawler in Ruby
Actors and Threads
Scaling Apache Storm - Strata + Hadoop World 2014
Ad

Similar to Ruby Concurrency and EventMachine (20)

KEY
Some Rough Fibrous Material
PDF
Ruby19 osdc-090418222718-phpapp02
PDF
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
KEY
The Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RI
PDF
Node Boot Camp
PDF
Ruby thread safety first
PPTX
Ruby introduction part1
KEY
A tour on ruby and friends
KEY
Introduction to Actor Model and Akka
PDF
Intro to React
PDF
Nzpug welly-cassandra-02-12-2010
PPT
openmp.ppt
PPT
openmp.ppt
PPTX
Python basics
PPTX
Python basics
PPTX
Python basics
PPTX
Python basics
PPTX
Python basics
PPTX
Python basics
PPTX
Python basics
Some Rough Fibrous Material
Ruby19 osdc-090418222718-phpapp02
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
The Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RI
Node Boot Camp
Ruby thread safety first
Ruby introduction part1
A tour on ruby and friends
Introduction to Actor Model and Akka
Intro to React
Nzpug welly-cassandra-02-12-2010
openmp.ppt
openmp.ppt
Python basics
Python basics
Python basics
Python basics
Python basics
Python basics
Python basics

Recently uploaded (20)

PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
MYSQL Presentation for SQL database connectivity
PDF
KodekX | Application Modernization Development
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
cuic standard and advanced reporting.pdf
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
MIND Revenue Release Quarter 2 2025 Press Release
Unlocking AI with Model Context Protocol (MCP)
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Reach Out and Touch Someone: Haptics and Empathic Computing
NewMind AI Weekly Chronicles - August'25 Week I
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
20250228 LYD VKU AI Blended-Learning.pptx
Review of recent advances in non-invasive hemoglobin estimation
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
MYSQL Presentation for SQL database connectivity
KodekX | Application Modernization Development
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
cuic standard and advanced reporting.pdf
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Advanced methodologies resolving dimensionality complications for autism neur...
“AI and Expert System Decision Support & Business Intelligence Systems”
Encapsulation_ Review paper, used for researhc scholars
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx

Ruby Concurrency and EventMachine

  • 1. Ruby Concurrency ...and the mysterious case of the Reactor Pattern Christopher Spring
  • 3. WTF the EventMachine and why should I care?
  • 4. WTF the EventMachine and why should I care?
  • 5. WTF the EventMachine and why should I care?
  • 6. Resource utilization • Lots of IO (90/10) • Disk • Network • system() • Lots of cores http://www.mikeperham.com/2010/01/27/scalable-ruby-processing-with-eventmachine/
  • 7. Ruby concurrency basics • Threads • Fibers • Processes
  • 8. Threading Models 1: N 1 :1 M :N
  • 9. Threading Models 1: N Kernel Threads 1 :1 User Threads M :N
  • 10. Threading Models 1: N 1 :1 M :N Kernel Threads User Threads
  • 11. Threading Models 1: N • Green Threads • Ruby 1.8 1 :1 • Pros/Cons M :N Kernel Threads User Threads
  • 12. Threading Models 1: N 1 :1 M :N Kernel Threads User Threads
  • 13. Threading Models 1: N • Native Threads • Ruby 1.9 / jRuby 1 :1 • Pros/Cons M :N Kernel Threads User Threads
  • 14. Threading Models 1: N 1 :1 ? M :N Kernel Threads User Threads
  • 16. Threads • Shared state and memory space
  • 17. Threads • Shared state and memory space • Relatively light weight
  • 18. Threads • Shared state and memory space • Relatively light weight • Preemptive scheduling
  • 20. Ruby has baggage: GIL http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/
  • 23. Threads... suck • Race conditions • Deadlocks
  • 24. Threads... suck • Race conditions • Deadlocks • Hard to debug
  • 25. Threads... suck • Race conditions • Deadlocks • Hard to debug • GIL
  • 26. Threads... suck • Race conditions • Deadlocks • Hard to debug • GIL
  • 28. Fibers • It’s a coroutine, dammit!
  • 29. Fibers • It’s a coroutine, dammit! • “... [component to] generalize subroutines to allow multiple entry points for suspending and resuming execution at certain locations.”
  • 30. file_iterator = Fiber.new do file = File.open('stuff.csv', 'r') while line = file.gets Fiber.yield line end file.close end 3.times{ file_iterator.resume } # => line 1 # => line 2 # => line 3
  • 31. Fibers • Cooperative Scheduling • Very lightweight • Maintains state • Great for: cooperative tasks, iterators, infinite lists and pipes
  • 32. def interpret_csv( csv_source ) Fiber.new do while csv_source.alive? str = csv_source.resume Fiber.yield str.split(',').map(&:strip) end end end def file_iterator(file_name) Fiber.new do file = File.open(file_name, 'r') while line = file.gets Fiber.yield line end file.close end end interpret_csv( file_iterator('stuff.csv') ).resume # => [...]
  • 34. Client Client Client Client IO Stream Event Handler A Event Dispatcher Event Handler B Demultiplexer Event Handler C Event Handler D
  • 35. Benefits • Non blocking IO • Coarse grain concurrency • No threads! • Single Process
  • 36. Limitations • Hard to debug • Dispatch to event handlers is synchronous • Demultiplexer polling limits
  • 38. require 'eventmachine' class EchoServer < EM::Connection def post_init puts "New connecting" end def unbind puts "Connection closed" end def receive_data(data) # unbuffered!! puts "<< #{data}" send_data ">> #{data}" end end EM.run do EM.start_server('127.0.0.1', 9000, EchoServer) puts "Started server at 127.0.0.1:9000" end # Runs till EM.stop called
  • 39. # $ telnet localhost 9000 require 'eventmachine' # Hello # >> Hello class EchoServer < EM::Connection # Bye def post_init # >> Bye puts "New connecting" end def unbind puts "Connection closed" end def receive_data(data) # unbuffered!! puts "<< #{data}" send_data ">> #{data}" end end EM.run do EM.start_server('127.0.0.1', 9000, EchoServer) puts "Started server at 127.0.0.1:9000" end # Runs till EM.stop called
  • 40. Primitives • run loop • next_tick; add_timer; add_periodic_timer • EM.defer • EM::Queue • EM::Channel
  • 41. EM.run do Defer operation = Proc.new do puts 'MapMap!!' sleep 3 puts 'Done collecting data' [1, 1, 2, 3, 5, 8, 13] end callback = Proc.new do |arr| puts 'Reducing...' sleep 1 puts 'Reduced' puts arr.inject(:+) EM.stop end EM.defer(operation, callback) end
  • 42. EM.run do Defer # # # MapMap!! Done collecting data Reducing... # Reduced operation = Proc.new do # 33 puts 'MapMap!!' sleep 3 puts 'Done collecting data' [1, 1, 2, 3, 5, 8, 13] end callback = Proc.new do |arr| puts 'Reducing...' sleep 1 puts 'Reduced' puts arr.inject(:+) EM.stop end EM.defer(operation, callback) end
  • 43. EM.run do Queue queue = EM::Queue.new EM.defer do sleep 2; queue.push 'Mail 1' sleep 3; queue.push 'Mail 2' sleep 4; queue.push 'Mail 3' end mail_sender = Proc.new do |mail| puts "Sending #{mail}" EM.next_tick{ queue.pop(&mail_sender)} end queue.pop(&mail_sender) end
  • 44. Channel EM.run do channel = EM::Channel.new EM.defer do channel.subscribe do |msg| puts "Received #{msg}" end end EM.add_periodic_timer(1) do channel << Time.now end end
  • 45. class Mailer include EM::Deferrable Deferrable def initialize callback do sleep 1 puts 'Updated statistics!' end errback{ puts 'retrying mail'} end def send rand >= 0.5 ? succeed : fail end end EM.run do 5.times do mailer = Mailer.new EM.add_timer(rand * 5){ mailer.send} end end
  • 46. class Mailer include EM::Deferrable Deferrable def initialize # Updating statistics! callback do # Updating statistics! sleep 1 # retrying mail puts 'Updated statistics!' end errback{ puts 'retrying mail'} end def send rand >= 0.5 ? succeed : fail end end EM.run do 5.times do mailer = Mailer.new EM.add_timer(rand * 5){ mailer.send} end end
  • 47. class Mailer Stacked callbacks include EM::Deferrable EM.run do def add_mailing(val) m = Mailer.new callback{ m.add_mailing(1) sleep 1; m.add_mailing(2) puts "Sent #{val}" m.connection_open! } end EM.add_timer(1) do m.connection_lost! def connection_open! EM.add_timer(2) do puts 'Open connection' m.add_mailing(3) succeed m.add_mailing(4) end m.connection_open! end def connection_lost! end puts 'Lost connection' end set_deferred_status nil end end
  • 48. class Mailer Stacked callbacks include EM::Deferrable EM.run do def add_mailing(val) m = Mailer.new callback{ # Open connection m.add_mailing(1) sleep 1; m.add_mailing(2) # Sent 1 puts "Sent #{val}" m.connection_open! # Sent 2 } end # Lost connection EM.add_timer(1) do # Open connection m.connection_lost! def connection_open! # Sent 3 EM.add_timer(2) do puts 'Open connection' m.add_mailing(3) # Sent 4 succeed m.add_mailing(4) end m.connection_open! end def connection_lost! end puts 'Lost connection' end set_deferred_status nil end end
  • 49. Gotchas • Synchronous code will slow it down • Use/Write libraries for EM • Everything in the event loop must be async!
  • 50. Summary • It’s a blocking world! • Alternative concurrency implementations • Start playing with EM
  • 51. Worth checking out • EM-Synchrony: https://github.com/igrigorik/em-synchrony • Goliath: https://github.com/postrank-labs/goliath

Editor's Notes

  • #2: \n
  • #3: \n
  • #4: \n
  • #5: \n
  • #6: \n
  • #7: \n
  • #8: \n
  • #9: \n
  • #10: Pros: Lots of threads; Cheap to create, execute &amp; cleanup\nCons: Kernel doesn&amp;#x2019;t know about threads; Blocking\ne.g. new green thread for every http request that comes in... \n
  • #11: Pros: Non blocking; Multi core systems; Shared memory\nCons: Expensive to create; complex context switching; far fewer threads\n
  • #12: Pros: Best of both worlds: Multiple CPUS; Not all threads blocked by system calls; Cheap creation, execution &amp; cleanup\nCons: Green threads blocking on IO can block other Green threads in kernel thread; Hard; Kernel and User scheduler need to work together\n
  • #13: Resource utilization\nAsync IO\n
  • #14: Resource utilization\nAsync IO\n
  • #15: Resource utilization\nAsync IO\n
  • #16: \n
  • #17: Ruby has a legacy of being thread unsafe (e.g. rails only became thread safe 2.2&amp;#x2018;ish)\n1.9 Ruby code does not execute on more than one thread concurrently!\n
  • #18: \n
  • #19: \n
  • #20: \n
  • #21: \n
  • #22: \n
  • #23: \n
  • #24: \n
  • #25: \n
  • #26: Fast and cheap to setup\n
  • #27: \n
  • #28: \n
  • #29: \n
  • #30: \n
  • #31: Inverted flow control (callback hell)\n... which limit concurrency\n\n
  • #32: Toolkit for creating evented apps\n
  • #33: EM interchangeable with EventMachine\n
  • #34: next_tick -&gt; run code at the next opportunity (always run in main thread)\ndefer -&gt; defer work to run on a thread (green) - 20 by default\nQueue -&gt; data\nChannel -&gt; comms\n
  • #35: \n
  • #36: \n
  • #37: \n
  • #38: \n
  • #39: \n
  • #40: \n
  • #41: \n
  • #42: \n
  • #43: \n
  • #44: \n
  • #45: \n
  • #46: \n