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

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 

Kürzlich hochgeladen (20)

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 

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