SlideShare a Scribd company logo
1 of 39
Download to read offline
The Code of Forking Paths
Karel Minařík
Karel Minařík
→ Independent web designer and developer

→ Ruby, Rails, Git and CouchDB propagandista in .cz

→ Previously: Flash Developer; Art Director; Information Architect;… (see LinkedIn)

→ @karmiq at Twitter




→   karmi.cz



                                                                                      The Code of Forking Paths
“He believed in an infinite series of times, in a growing,
dizzying net of divergent, convergent and parallel
times. (...) We do not exist in the majority of these
times; in some you exist, and not I; in others I, and not
you; in others, both of us. In the present one, which
a favorable fate has granted me, you have arrived at my
house; in another, while crossing the garden, you found
me dead; in still another, I utter these same words, but
I am a mistake, a ghost.”
http://en.wikipedia.org/wiki/
The_Garden_of_Forking_Paths




                                The Code of Forking Paths
THE CODE OF FORKING PATHS

Parallel presence




               HTTP/1.1  503  Service  Unavailable
               HTTP/1.1  201  Created




                                                 The Code of Forking Paths
THE CODE OF FORKING PATHS

Ataxo Social Insider




                            The Code of Forking Paths
1   Asynchronous Task Processing




                                   The Code of Forking Paths
THE CODE OF FORKING PATHS

Asynchronous Task Processing




Long running requests

Canonical Example: video upload and conversion




                                         The Code of Forking Paths
Request    WORKLOAD      Response




Request   NOTIFICATION   Response


           WORKLOAD




                                    The Code of Forking Paths
THE CODE OF FORKING PATHS

„Engineering“ solution



class  UploadController  <  ApplicationController

    def  create
        #  ....
        Thread.new  do
            #  ***  WORK  REALLY  HARD  <HERE>  ***   What could possibly go wrong?
        end
        render  :text  =>  "KTHXBAI!"
    end

end




                                                            The Code of Forking Paths
THE CODE OF FORKING PATHS

The Task Queue




class  UploadController  <  ApplicationController

    def  create
        #  Store  uploaded  file,  store  record
        put_the_video_on_the_processing_queue(@video.id)
        render  :text  =>  "Thanks!  Your  video  is  being  processed."
    end

end




                                                                 The Code of Forking Paths
REDIS

How Does It Work?



                                                                                                  RPUSH




                                         }
                            LPOP




    O(1)                                             Millions of items




                       https://github.com/defunkt/resque/blob/v1.13.0/lib/resque.rb#L133-138




http://redis.io/commands#list                                                                  The Code of Forking Paths
TASK QUEUES

Poor-man’s Queues



 1   „Publisher”
/usr/local/bin/redis-­‐cli  RPUSH  "queue"  "task-­‐01"




 2   „Worker”
while  true;  do  /usr/local/bin/redis-­‐cli  BLPOP  "queue"  0;  done




                                                          The Code of Forking Paths
TASK QUEUES

Poor-man’s Queues


 1   „Publisher”
/usr/local/bin/redis-­‐cli  RPUSH  "queue"  "task-­‐01"



 2   „Worker”
while  true;  do
    /usr/local/bin/redis-­‐cli  BLPOP  "queue"  0
    /usr/local/bin/redis-­‐cli  PUBLISH  "queue:messages"  "Processed  task."
done


 3   „Monitor”
/usr/local/bin/redis-­‐cli  SUBSCRIBE  "queue:messages"



                                            Demo
                                                               The Code of Forking Paths
require "redis"
                                 require "nest"

                                 module Ost
                                   VERSION = "0.0.1"
                                   TIMEOUT = ENV["OST_TIMEOUT"] || 2

                                   class Queue
                                     attr :ns

                                     def initialize(name)
                                       @ns = Nest.new(:ost)[name]
                                     end

                                     def push(value)
                                       redis.lpush(ns, value)
                                     end

                                     def each(&block)
                                       loop do
                                         _, item = redis.brpop(ns, TIMEOUT)
                                         next if item.nil? or item.empty?

                                         begin
                                           block.call(item)
                                         rescue Exception => e
                                           error = "#{Time.now} #{ns[item]} => #{e.inspect}"

                                           redis.rpush   ns[:errors], error
                                           redis.publish ns[:errors], error
                                         end
                                       end
                                     end

                                     def errors
                                       redis.lrange ns[:errors], 0, -1
                                     end

                                     alias << push
                                     alias pop each

                                   private

                                     def redis
                                       Ost.redis
                                     end
                                   end

                                   @queues = Hash.new do |hash, key|
                                     hash[key] = Queue.new(key)
                                   end

                                   def self.[](queue)
                                     @queues[queue]
                                   end

                                   def self.connect(options = {})
                                     @redis = Redis.connect(options)
                                   end

                                   def self.redis
                                     @redis ||= Redis.connect
                                   end

                                   def self.redis=(redis)
                                     @redis = redis
                                   end
                                 end


https://github.com/soveran/ost
Demo




https://github.com/karmi/resque-demo
Demo




http://git.karmi.cz/resque_job_polling_demo.git
2   „Messaging”




                  The Code of Forking Paths
MESSAGING

„Object Oriented Programming”


 I'm sorry that I long ago coined the term "objects" for this
topic because it gets many people to focus on the lesser idea.
e big idea is "messaging" (...).
e key in making great and growable systems is much more
to design how its modules communicate rather than what
their internal properties and behaviors should be.


— Alan Kay, prototypes vs classes was: Re: Sun's HotSpot



http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html   The Code of Forking Paths
MESSAGING

Three Overlooked Features of A Software System




Maintainability     (changing features)

Extensibility (adding or removing features)
Testability (validating features)




                                              The Code of Forking Paths
MESSAGING

Asynchronous Task Processing in A Real World


When you place your order the cashier marks a coffee cup
with your order and places it into the queue. e queue is
quite literally a queue of coffee cups lined up on top of the
espresso machine. is queue decouples cashier and barista
and allows the cashier to keep taking orders even if the
barista is backed up for a moment.


— Gregor Hohpe, Starbucks Does Not Use Two-Phase Commit

http://www.eaipatterns.com/ramblings/18_starbucks.html   The Code of Forking Paths
Message Queue
Workers
MESSAGING

AMQP




            Alvaro Videla and Jason J.W. Williams, RabbitMQ in Action
            p. 16


                                                                    The Code of Forking Paths
AMQP

Exchanges, Queues and Bindings




       Alvaro Videla and Jason J.W. Williams, RabbitMQ in Action
       p. 30


                                                               The Code of Forking Paths
The Code of Forking Paths
AMQP

Publishers and Consumers

 1    Publisher
exchange  =  MQ.topic('log')
exchange.publish(  {:level  =>  level,
                                      :time    =>  Time.now,            Message
                                      :body    =>  message}.to_json,

                                      :key      =>  "log.#{level}"  )   Routing Key


 2    Consumer (all logs)
MQ.queue("all  logs").bind(  MQ.topic('log'),  :key  =>  "log.*"  ).subscribe  do  |header,  message|
    ...
end




 3    Consumer (error logs)
MQ.queue("error  logs").bind(  MQ.topic('log'),  :key  =>  "log.error"  ).subscribe  do  |message|
    ...
end




                                                                                  The Code of Forking Paths
Thumbs up!!!
ASYNCHRONOUS WORLD

Evented Programming



$.get('/data',  function(data)  {
    $('.result').html(data);
    alert('Loaded  data  from  the  server.');
});




 var  mydata  =  $.get('/data');



                                          The Code of Forking Paths
Ry Dahl, Node.js (2009)
http://nodejs.org
http://s3.amazonaws.com/four.livejournal/20091117/jsconf.pdf
module BalancingProxy
  # ...
  module Callbacks

      def on_select
        lambda do |backend|
          puts "Selected backend: #{backend.url}"
          backend.increment_counter if Backend.strategy == :balanced
        end
      end

      def on_connect
        lambda do |backend|           module  Server
          puts "Connected"
                                              #  ...
        end
      end                                     Backend.select  do  |backend|
                                                  conn.server  backend,  :host  =>  backend.host,  :port  =>  backend.port
      def on_data
        lambda do |data|                          conn.on_connect    &Callbacks.on_connect
          puts "Receiving data"
                                                  conn.on_data          &Callbacks.on_data
          data
        end                                       conn.on_response  &Callbacks.on_response
      end                                         conn.on_finish      &Callbacks.on_finish
                                              end
      def on_response                     end
        lambda do |backend, resp|
          puts "Handling response"
          resp
        end
      end

      def on_finish
        lambda do |backend|
          puts "Finished"
          backend.decrement_counter if Backend.strategy == :balanced
        end
      end

  end

end



https://github.com/igrigorik/em-proxy/blob/master/examples/balancing.rb                           The Code of Forking Paths
THE CODE OF FORKING PATHS

Resume




➡    Long-running Tasks
➡    Task Queues (Redis, Resque)
➡    Maintainability, Extensibility, Testability
➡    “Monadic” Architecture (of loosely coupled parts)
➡    Messaging: AMQP, Publisher/Consumer, Routing



                                               The Code of Forking Paths
THE CODE OF FORKING PATHS

Watch Online




Watch this lecture online (in Czech):
http://multimedia.vse.cz/media/Viewer/?peid=51c06c512f4645289c4e9c749dc85acc1d


                                                            The Code of Forking Paths
Thanks!
  d

More Related Content

Viewers also liked

vSphere APIs for performance monitoring
vSphere APIs for performance monitoringvSphere APIs for performance monitoring
vSphere APIs for performance monitoring
Alan Renouf
 
Redis — The AK-47 of Post-relational Databases
Redis — The AK-47 of Post-relational DatabasesRedis — The AK-47 of Post-relational Databases
Redis — The AK-47 of Post-relational Databases
Karel Minarik
 
Monitoring in an Infrastructure as Code Age
Monitoring in an Infrastructure as Code AgeMonitoring in an Infrastructure as Code Age
Monitoring in an Infrastructure as Code Age
Puppet
 

Viewers also liked (12)

vSphere APIs for performance monitoring
vSphere APIs for performance monitoringvSphere APIs for performance monitoring
vSphere APIs for performance monitoring
 
Dlsecyx pgroammr (Dyslexic Programmer - cool stuff for scaling)
Dlsecyx pgroammr (Dyslexic Programmer - cool stuff for scaling)Dlsecyx pgroammr (Dyslexic Programmer - cool stuff for scaling)
Dlsecyx pgroammr (Dyslexic Programmer - cool stuff for scaling)
 
PostgreSQL Materialized Views with Active Record
PostgreSQL Materialized Views with Active RecordPostgreSQL Materialized Views with Active Record
PostgreSQL Materialized Views with Active Record
 
The Complete MariaDB Server Tutorial - Percona Live 2015
The Complete MariaDB Server Tutorial - Percona Live 2015The Complete MariaDB Server Tutorial - Percona Live 2015
The Complete MariaDB Server Tutorial - Percona Live 2015
 
Redis — The AK-47 of Post-relational Databases
Redis — The AK-47 of Post-relational DatabasesRedis — The AK-47 of Post-relational Databases
Redis — The AK-47 of Post-relational Databases
 
Taking Control of Chaos with Docker and Puppet
Taking Control of Chaos with Docker and PuppetTaking Control of Chaos with Docker and Puppet
Taking Control of Chaos with Docker and Puppet
 
Detecting headless browsers
Detecting headless browsersDetecting headless browsers
Detecting headless browsers
 
Monitoring in an Infrastructure as Code Age
Monitoring in an Infrastructure as Code AgeMonitoring in an Infrastructure as Code Age
Monitoring in an Infrastructure as Code Age
 
How to make keynote like presentation with markdown
How to make keynote like presentation with markdownHow to make keynote like presentation with markdown
How to make keynote like presentation with markdown
 
Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12
Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12
Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12
 
Lessons I Learned While Scaling to 5000 Puppet Agents
Lessons I Learned While Scaling to 5000 Puppet AgentsLessons I Learned While Scaling to 5000 Puppet Agents
Lessons I Learned While Scaling to 5000 Puppet Agents
 
Orchestrating Docker containers at scale
Orchestrating Docker containers at scaleOrchestrating Docker containers at scale
Orchestrating Docker containers at scale
 

More from Karel Minarik

Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]
Karel Minarik
 
Úvod do programování 3 (to be continued)
Úvod do programování 3 (to be continued)Úvod do programování 3 (to be continued)
Úvod do programování 3 (to be continued)
Karel Minarik
 

More from Karel Minarik (20)

Vizualizace dat a D3.js [EUROPEN 2014]
Vizualizace dat a D3.js [EUROPEN 2014]Vizualizace dat a D3.js [EUROPEN 2014]
Vizualizace dat a D3.js [EUROPEN 2014]
 
Elasticsearch (Rubyshift 2013)
Elasticsearch (Rubyshift 2013)Elasticsearch (Rubyshift 2013)
Elasticsearch (Rubyshift 2013)
 
Elasticsearch in 15 Minutes
Elasticsearch in 15 MinutesElasticsearch in 15 Minutes
Elasticsearch in 15 Minutes
 
Realtime Analytics With Elasticsearch [New Media Inspiration 2013]
Realtime Analytics With Elasticsearch [New Media Inspiration 2013]Realtime Analytics With Elasticsearch [New Media Inspiration 2013]
Realtime Analytics With Elasticsearch [New Media Inspiration 2013]
 
Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]
 
Shell's Kitchen: Infrastructure As Code (Webexpo 2012)
Shell's Kitchen: Infrastructure As Code (Webexpo 2012)Shell's Kitchen: Infrastructure As Code (Webexpo 2012)
Shell's Kitchen: Infrastructure As Code (Webexpo 2012)
 
Elastic Search: Beyond Ordinary Fulltext Search (Webexpo 2011 Prague)
Elastic Search: Beyond Ordinary Fulltext Search (Webexpo 2011 Prague)Elastic Search: Beyond Ordinary Fulltext Search (Webexpo 2011 Prague)
Elastic Search: Beyond Ordinary Fulltext Search (Webexpo 2011 Prague)
 
Your Data, Your Search, ElasticSearch (EURUKO 2011)
Your Data, Your Search, ElasticSearch (EURUKO 2011)Your Data, Your Search, ElasticSearch (EURUKO 2011)
Your Data, Your Search, ElasticSearch (EURUKO 2011)
 
CouchDB – A Database for the Web
CouchDB – A Database for the WebCouchDB – A Database for the Web
CouchDB – A Database for the Web
 
Spoiling The Youth With Ruby (Euruko 2010)
Spoiling The Youth With Ruby (Euruko 2010)Spoiling The Youth With Ruby (Euruko 2010)
Spoiling The Youth With Ruby (Euruko 2010)
 
Verzovani kodu s Gitem (Karel Minarik)
Verzovani kodu s Gitem (Karel Minarik)Verzovani kodu s Gitem (Karel Minarik)
Verzovani kodu s Gitem (Karel Minarik)
 
Představení Ruby on Rails [Junior Internet]
Představení Ruby on Rails [Junior Internet]Představení Ruby on Rails [Junior Internet]
Představení Ruby on Rails [Junior Internet]
 
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)
 
Úvod do Ruby on Rails
Úvod do Ruby on RailsÚvod do Ruby on Rails
Úvod do Ruby on Rails
 
Úvod do programování 7
Úvod do programování 7Úvod do programování 7
Úvod do programování 7
 
Úvod do programování 6
Úvod do programování 6Úvod do programování 6
Úvod do programování 6
 
Úvod do programování 5
Úvod do programování 5Úvod do programování 5
Úvod do programování 5
 
Úvod do programování 4
Úvod do programování 4Úvod do programování 4
Úvod do programování 4
 
Úvod do programování 3 (to be continued)
Úvod do programování 3 (to be continued)Úvod do programování 3 (to be continued)
Úvod do programování 3 (to be continued)
 
Historie programovacích jazyků
Historie programovacích jazykůHistorie programovacích jazyků
Historie programovacích jazyků
 

Recently uploaded

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
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
Enterprise Knowledge
 

Recently uploaded (20)

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
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
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
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
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
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
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony 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)
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 

The Code Of The Forking Paths (Asynchronous Processing with Resque and AMQP)

  • 1. The Code of Forking Paths Karel Minařík
  • 2. Karel Minařík → Independent web designer and developer → Ruby, Rails, Git and CouchDB propagandista in .cz → Previously: Flash Developer; Art Director; Information Architect;… (see LinkedIn) → @karmiq at Twitter → karmi.cz The Code of Forking Paths
  • 3.
  • 4. “He believed in an infinite series of times, in a growing, dizzying net of divergent, convergent and parallel times. (...) We do not exist in the majority of these times; in some you exist, and not I; in others I, and not you; in others, both of us. In the present one, which a favorable fate has granted me, you have arrived at my house; in another, while crossing the garden, you found me dead; in still another, I utter these same words, but I am a mistake, a ghost.”
  • 6. THE CODE OF FORKING PATHS Parallel presence HTTP/1.1  503  Service  Unavailable HTTP/1.1  201  Created The Code of Forking Paths
  • 7. THE CODE OF FORKING PATHS Ataxo Social Insider The Code of Forking Paths
  • 8. 1 Asynchronous Task Processing The Code of Forking Paths
  • 9. THE CODE OF FORKING PATHS Asynchronous Task Processing Long running requests Canonical Example: video upload and conversion The Code of Forking Paths
  • 10. Request WORKLOAD Response Request NOTIFICATION Response WORKLOAD The Code of Forking Paths
  • 11. THE CODE OF FORKING PATHS „Engineering“ solution class  UploadController  <  ApplicationController    def  create        #  ....        Thread.new  do            #  ***  WORK  REALLY  HARD  <HERE>  *** What could possibly go wrong?        end        render  :text  =>  "KTHXBAI!"    end end The Code of Forking Paths
  • 12. THE CODE OF FORKING PATHS The Task Queue class  UploadController  <  ApplicationController    def  create        #  Store  uploaded  file,  store  record        put_the_video_on_the_processing_queue(@video.id)        render  :text  =>  "Thanks!  Your  video  is  being  processed."    end end The Code of Forking Paths
  • 13.
  • 14.
  • 15. REDIS How Does It Work? RPUSH } LPOP O(1) Millions of items https://github.com/defunkt/resque/blob/v1.13.0/lib/resque.rb#L133-138 http://redis.io/commands#list The Code of Forking Paths
  • 16. TASK QUEUES Poor-man’s Queues 1 „Publisher” /usr/local/bin/redis-­‐cli  RPUSH  "queue"  "task-­‐01" 2 „Worker” while  true;  do  /usr/local/bin/redis-­‐cli  BLPOP  "queue"  0;  done The Code of Forking Paths
  • 17. TASK QUEUES Poor-man’s Queues 1 „Publisher” /usr/local/bin/redis-­‐cli  RPUSH  "queue"  "task-­‐01" 2 „Worker” while  true;  do    /usr/local/bin/redis-­‐cli  BLPOP  "queue"  0    /usr/local/bin/redis-­‐cli  PUBLISH  "queue:messages"  "Processed  task." done 3 „Monitor” /usr/local/bin/redis-­‐cli  SUBSCRIBE  "queue:messages" Demo The Code of Forking Paths
  • 18. require "redis" require "nest" module Ost VERSION = "0.0.1" TIMEOUT = ENV["OST_TIMEOUT"] || 2 class Queue attr :ns def initialize(name) @ns = Nest.new(:ost)[name] end def push(value) redis.lpush(ns, value) end def each(&block) loop do _, item = redis.brpop(ns, TIMEOUT) next if item.nil? or item.empty? begin block.call(item) rescue Exception => e error = "#{Time.now} #{ns[item]} => #{e.inspect}" redis.rpush ns[:errors], error redis.publish ns[:errors], error end end end def errors redis.lrange ns[:errors], 0, -1 end alias << push alias pop each private def redis Ost.redis end end @queues = Hash.new do |hash, key| hash[key] = Queue.new(key) end def self.[](queue) @queues[queue] end def self.connect(options = {}) @redis = Redis.connect(options) end def self.redis @redis ||= Redis.connect end def self.redis=(redis) @redis = redis end end https://github.com/soveran/ost
  • 21. 2 „Messaging” The Code of Forking Paths
  • 22. MESSAGING „Object Oriented Programming” I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea. e big idea is "messaging" (...). e key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be. — Alan Kay, prototypes vs classes was: Re: Sun's HotSpot http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html The Code of Forking Paths
  • 23. MESSAGING Three Overlooked Features of A Software System Maintainability (changing features) Extensibility (adding or removing features) Testability (validating features) The Code of Forking Paths
  • 24. MESSAGING Asynchronous Task Processing in A Real World When you place your order the cashier marks a coffee cup with your order and places it into the queue. e queue is quite literally a queue of coffee cups lined up on top of the espresso machine. is queue decouples cashier and barista and allows the cashier to keep taking orders even if the barista is backed up for a moment. — Gregor Hohpe, Starbucks Does Not Use Two-Phase Commit http://www.eaipatterns.com/ramblings/18_starbucks.html The Code of Forking Paths
  • 27. MESSAGING AMQP Alvaro Videla and Jason J.W. Williams, RabbitMQ in Action p. 16 The Code of Forking Paths
  • 28. AMQP Exchanges, Queues and Bindings Alvaro Videla and Jason J.W. Williams, RabbitMQ in Action p. 30 The Code of Forking Paths
  • 29. The Code of Forking Paths
  • 30. AMQP Publishers and Consumers 1 Publisher exchange  =  MQ.topic('log') exchange.publish(  {:level  =>  level,                                      :time    =>  Time.now, Message                                      :body    =>  message}.to_json,                                      :key      =>  "log.#{level}"  ) Routing Key 2 Consumer (all logs) MQ.queue("all  logs").bind(  MQ.topic('log'),  :key  =>  "log.*"  ).subscribe  do  |header,  message|    ... end 3 Consumer (error logs) MQ.queue("error  logs").bind(  MQ.topic('log'),  :key  =>  "log.error"  ).subscribe  do  |message|    ... end The Code of Forking Paths
  • 31.
  • 33. ASYNCHRONOUS WORLD Evented Programming $.get('/data',  function(data)  {    $('.result').html(data);    alert('Loaded  data  from  the  server.'); }); var  mydata  =  $.get('/data'); The Code of Forking Paths
  • 34. Ry Dahl, Node.js (2009) http://nodejs.org
  • 36. module BalancingProxy # ... module Callbacks def on_select lambda do |backend| puts "Selected backend: #{backend.url}" backend.increment_counter if Backend.strategy == :balanced end end def on_connect lambda do |backend| module  Server puts "Connected"        #  ... end end        Backend.select  do  |backend|            conn.server  backend,  :host  =>  backend.host,  :port  =>  backend.port def on_data lambda do |data|            conn.on_connect    &Callbacks.on_connect puts "Receiving data"            conn.on_data          &Callbacks.on_data data end            conn.on_response  &Callbacks.on_response end            conn.on_finish      &Callbacks.on_finish        end def on_response    end lambda do |backend, resp| puts "Handling response" resp end end def on_finish lambda do |backend| puts "Finished" backend.decrement_counter if Backend.strategy == :balanced end end end end https://github.com/igrigorik/em-proxy/blob/master/examples/balancing.rb The Code of Forking Paths
  • 37. THE CODE OF FORKING PATHS Resume ➡ Long-running Tasks ➡ Task Queues (Redis, Resque) ➡ Maintainability, Extensibility, Testability ➡ “Monadic” Architecture (of loosely coupled parts) ➡ Messaging: AMQP, Publisher/Consumer, Routing The Code of Forking Paths
  • 38. THE CODE OF FORKING PATHS Watch Online Watch this lecture online (in Czech): http://multimedia.vse.cz/media/Viewer/?peid=51c06c512f4645289c4e9c749dc85acc1d The Code of Forking Paths