SlideShare ist ein Scribd-Unternehmen logo
1 von 55
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 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
Baie Dankie!
Questions?
Links

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

Weitere ähnliche Inhalte

Was ist angesagt?

Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Using Node.js to  Build Great  Streaming Services - HTML5 Dev ConfUsing Node.js to  Build Great  Streaming Services - HTML5 Dev Conf
Using Node.js to Build Great Streaming Services - HTML5 Dev ConfTom Croucher
 
Implementações paralelas
Implementações paralelasImplementações paralelas
Implementações paralelasWillian Molinari
 
Dataflow: Declarative concurrency in Ruby
Dataflow: Declarative concurrency in RubyDataflow: Declarative concurrency in Ruby
Dataflow: Declarative concurrency in RubyLarry Diehl
 
When Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of TorqueboxWhen Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of Torqueboxrockyjaiswal
 
Javascript asynchronous
Javascript asynchronousJavascript asynchronous
Javascript asynchronouskang taehun
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseChristian Melchior
 
Rapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbRapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbikailan
 
Microarmy - by J2 Labs
Microarmy - by J2 LabsMicroarmy - by J2 Labs
Microarmy - by J2 LabsJames Dennis
 
Do more than one thing at the same time, the Python way
Do more than one thing at the same time, the Python wayDo more than one thing at the same time, the Python way
Do more than one thing at the same time, the Python wayJaime Buelta
 
Introduction to kotlin coroutines
Introduction to kotlin coroutinesIntroduction to kotlin coroutines
Introduction to kotlin coroutinesNAVER Engineering
 
Node.js streaming csv downloads proxy
Node.js streaming csv downloads proxyNode.js streaming csv downloads proxy
Node.js streaming csv downloads proxyIsmael Celis
 
Tornado Web Server Internals
Tornado Web Server InternalsTornado Web Server Internals
Tornado Web Server InternalsPraveen Gollakota
 
Introduction to orchestration using Mcollective
Introduction to orchestration using McollectiveIntroduction to orchestration using Mcollective
Introduction to orchestration using McollectivePuppet
 
Python, async web frameworks, and MongoDB
Python, async web frameworks, and MongoDBPython, async web frameworks, and MongoDB
Python, async web frameworks, and MongoDBemptysquare
 
Javascript Promises/Q Library
Javascript Promises/Q LibraryJavascript Promises/Q Library
Javascript Promises/Q Libraryasync_io
 

Was ist angesagt? (20)

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

Andere mochten auch

Ruby EventMachine + em-WebSocket
Ruby EventMachine + em-WebSocketRuby EventMachine + em-WebSocket
Ruby EventMachine + em-WebSocketCarlos Vasquez
 
Le 10 principali ragioni per cui Ruby fa pena
Le 10 principali ragioni per cui Ruby fa penaLe 10 principali ragioni per cui Ruby fa pena
Le 10 principali ragioni per cui Ruby fa penaAdvenias
 
Eventdriven I/O - A hands on introduction
Eventdriven I/O - A hands on introductionEventdriven I/O - A hands on introduction
Eventdriven I/O - A hands on introductionMarc Seeger
 
Multi-threaded web crawler in Ruby
Multi-threaded web crawler in RubyMulti-threaded web crawler in Ruby
Multi-threaded web crawler in RubyPolcode
 
Actors and Threads
Actors and ThreadsActors and Threads
Actors and Threadsmperham
 
Scaling Apache Storm - Strata + Hadoop World 2014
Scaling Apache Storm - Strata + Hadoop World 2014Scaling Apache Storm - Strata + Hadoop World 2014
Scaling Apache Storm - Strata + Hadoop World 2014P. Taylor Goetz
 

Andere mochten auch (8)

jRuby and TorqueBox
jRuby and TorqueBoxjRuby and TorqueBox
jRuby and TorqueBox
 
Ruby EventMachine + em-WebSocket
Ruby EventMachine + em-WebSocketRuby EventMachine + em-WebSocket
Ruby EventMachine + em-WebSocket
 
Event Machine
Event MachineEvent Machine
Event Machine
 
Le 10 principali ragioni per cui Ruby fa pena
Le 10 principali ragioni per cui Ruby fa penaLe 10 principali ragioni per cui Ruby fa pena
Le 10 principali ragioni per cui Ruby fa pena
 
Eventdriven I/O - A hands on introduction
Eventdriven I/O - A hands on introductionEventdriven I/O - A hands on introduction
Eventdriven I/O - A hands on introduction
 
Multi-threaded web crawler in Ruby
Multi-threaded web crawler in RubyMulti-threaded web crawler in Ruby
Multi-threaded web crawler in Ruby
 
Actors and Threads
Actors and ThreadsActors and Threads
Actors and Threads
 
Scaling Apache Storm - Strata + Hadoop World 2014
Scaling Apache Storm - Strata + Hadoop World 2014Scaling Apache Storm - Strata + Hadoop World 2014
Scaling Apache Storm - Strata + Hadoop World 2014
 

Ähnlich wie Ruby Concurrency and EventMachine

Some Rough Fibrous Material
Some Rough Fibrous MaterialSome Rough Fibrous Material
Some Rough Fibrous MaterialMurray Steele
 
Ruby19 osdc-090418222718-phpapp02
Ruby19 osdc-090418222718-phpapp02Ruby19 osdc-090418222718-phpapp02
Ruby19 osdc-090418222718-phpapp02Apoorvi Kapoor
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...bobmcwhirter
 
The Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RI
The Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RIThe Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RI
The Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RIEleanor McHugh
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 
Ruby thread safety first
Ruby thread safety firstRuby thread safety first
Ruby thread safety firstEmily Stolfo
 
Ruby introduction part1
Ruby introduction part1Ruby introduction part1
Ruby introduction part1Brady Cheng
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Introduction to Actor Model and Akka
Introduction to Actor Model and AkkaIntroduction to Actor Model and Akka
Introduction to Actor Model and AkkaYung-Lin Ho
 
Intro to React
Intro to ReactIntro to React
Intro to ReactTroy Miles
 
Nzpug welly-cassandra-02-12-2010
Nzpug welly-cassandra-02-12-2010Nzpug welly-cassandra-02-12-2010
Nzpug welly-cassandra-02-12-2010aaronmorton
 
openmp.ppt
openmp.pptopenmp.ppt
openmp.pptFAfazi1
 

Ähnlich wie Ruby Concurrency and EventMachine (20)

Some Rough Fibrous Material
Some Rough Fibrous MaterialSome Rough Fibrous Material
Some Rough Fibrous Material
 
Ruby19 osdc-090418222718-phpapp02
Ruby19 osdc-090418222718-phpapp02Ruby19 osdc-090418222718-phpapp02
Ruby19 osdc-090418222718-phpapp02
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
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
The Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RIThe Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RI
The Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RI
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Ruby thread safety first
Ruby thread safety firstRuby thread safety first
Ruby thread safety first
 
Ruby introduction part1
Ruby introduction part1Ruby introduction part1
Ruby introduction part1
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Introduction to Actor Model and Akka
Introduction to Actor Model and AkkaIntroduction to Actor Model and Akka
Introduction to Actor Model and Akka
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Nzpug welly-cassandra-02-12-2010
Nzpug welly-cassandra-02-12-2010Nzpug welly-cassandra-02-12-2010
Nzpug welly-cassandra-02-12-2010
 
openmp.ppt
openmp.pptopenmp.ppt
openmp.ppt
 
openmp.ppt
openmp.pptopenmp.ppt
openmp.ppt
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 
Python basics
Python basicsPython basics
Python basics
 

Kürzlich hochgeladen

Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 

Kürzlich hochgeladen (20)

Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 

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
  • 19.
  • 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
  • 52.
  • 55. Links • http://www.mikeperham.com • http://www.igvita.com (!!) • http://rubyeventmachine.com/

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. 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
  10. Pros: Non blocking; Multi core systems; Shared memory\nCons: Expensive to create; complex context switching; far fewer threads\n
  11. 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
  12. Resource utilization\nAsync IO\n
  13. Resource utilization\nAsync IO\n
  14. Resource utilization\nAsync IO\n
  15. \n
  16. 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
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. Fast and cheap to setup\n
  26. \n
  27. \n
  28. \n
  29. \n
  30. Inverted flow control (callback hell)\n... which limit concurrency\n\n
  31. Toolkit for creating evented apps\n
  32. EM interchangeable with EventMachine\n
  33. 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
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n