Your SlideShare is downloading. ×
0
Reactor Pattern
                       &

Event-Driven Programming
   A scalable concurrent approach,
   using EventMachin...
Reactor Pattern
                       &

Event-Driven Programming
   A scalable concurrent approach,
   using EventMachin...
Reactor Pattern
                             &

     Event-Driven Programming
http://godfat.org/slide/2010-04-13-reactor-p...
Table of Contents
• concurrency, why and how in network
• Event-Driven Programming explained in
  Flash with Ruby syntax

...
Event-Driven Programming
                        register method(:do_something)
loop{                   loop{
  # you cont...
Reactor Pattern
                register method(:handle)
loop{           loop{
  data = read     data = partial_read
  han...
Table of Contents




• how Thin works
• how EventMachine works
Table of Contents

• how Thin works
• how EventMachine works
Table of Contents

• how Thin works
• how EventMachine works
• how AMQP works
Table of Contents

• how Thin works
• how EventMachine works
• how AMQP works
• how Unicorn and Rainbows! works
Reactor Pattern
Request
(resource)
Reactor Pattern
                  EventMachine
Request
                  (demultiplexer
(resource)
                   + di...
Reactor Pattern
                  EventMachine
Request                            Thin (or AMQP)
                  (demult...
Reactor Pattern
                  EventMachine
Request                                Thin (or AMQP)
                  (de...
Reactor Pattern
                     EventMachine
Request                                         Thin (or AMQP)
         ...
Reactor Pattern
                             EventMachine
        Request                                         Thin (or...
your rails
application
                        Reactor Pattern
                                EventMachine
           Req...
how Thin works


                 Thin (or AMQP)
                 (request handler)
how Thin works
• Thin::Server
how Thin works
• Thin::Server
• Thin::Backends::TcpServer
 # communicate with EventMachine
how Thin works
• Thin::Server
• Thin::Backends::TcpServer
 # communicate with EventMachine

• Thin::Connection
 # EventMac...
how Thin works
• Thin::Server
• Thin::Backends::TcpServer
 # communicate with EventMachine

• Thin::Connection
 # EventMac...
how Thin works
Thin::Server
how Thin works
Thin::Server


           Backends::TcpServer
how Thin works
Thin::Server


           Backends::TcpServer




       Connection
how Thin works
Thin::Server


           Backends::TcpServer




       Connection


          Request
how Thin works
Thin::Server


           Backends::TcpServer




       Connection
               Connection


          R...
how Thin works
Thin::Server


           Backends::TcpServer




       Connection
               Connection
             ...
how Thin works
    thin 1.2.7 codename No Hup
how Thin works
              thin 1.2.7 codename No Hup

# in lib/thin/backends/tcp_server.rb:16
# in Thin::TcpServer#conn...
how Thin works
              thin 1.2.7 codename No Hup

# in lib/thin/connection.rb:42
# in Thin::Connection#receive_data...
how Thin works
                   thin 1.2.7 codename No Hup

     # in lib/thin/request.rb:82
     # in Thin::Request#par...
how Thin works
                     thin 1.2.7 codename No Hup

     // in ext/thin_parser/thin.c:335
     // in thin.c#Th...
how Thin works
                   thin 1.2.7 codename No Hup
     // in ext/thin_parser/parser.rl:102
     // in parser.rl...
how Thin works
                  thin 1.2.7 codename No Hup

Ragel is a finite state machine compiler with
output support f...
how Thin works
                  thin 1.2.7 codename No Hup

Ragel is a finite state machine compiler with
output support f...
how Thin works
              thin 1.2.7 codename No Hup

# in lib/thin/connection.rb:42
# in Thin::Connection#receive_data...
how Thin works
                 thin 1.2.7 codename No Hup

  # in lib/thin/connection.rb:52
  # in Thin::Connection#proce...
how EventMachine works
                  eventmachine 0.12.10

 # in lib/eventmachine.rb:1045
 # in EventMachine.defer
   ...
how Thin works
                   thin 1.2.7 codename No Hup

    # in lib/thin/connection.rb:68
    # in Thin::Connection...
how Thin works
              thin 1.2.7 codename No Hup

# in lib/thin/connection.rb:95
# in Thin::Connection#post_process...
Reactor Pattern
• resources
• synchronous event demultiplexer
• dispatcher
• request handler (Thin::Connection)


        ...
Table of Contents

• how Thin works
• how EventMachine works
• how AMQP works
• how Unicorn and Rainbows! works
how EventMachine works
          eventmachine 0.12.10
how EventMachine works
                    eventmachine 0.12.10
 # in lib/eventmachine.rb:571
 # in EventMachine.start_ser...
how EventMachine works
                   eventmachine 0.12.10
 # in lib/eventmachine.rb:50
   case $eventmachine_library
...
how EventMachine works
                   eventmachine 0.12.10
 # in lib/pr_eventmachine.rb:318
 # in EventMachine.run
  l...
how EventMachine works
                         eventmachine 0.12.10
       # in lib/eventmachine.rb:1445
       # in Even...
how Thin works
              thin 1.2.7 codename No Hup

# in lib/thin/connection.rb:42
# in Thin::Connection#receive_data...
how EventMachine works
                          eventmachine 0.12.10
        # in lib/eventmachine.rb:1427
        # in E...
how Thin works
              thin 1.2.7 codename No Hup

# in lib/thin/backends/tcp_server.rb:16
# in Thin::TcpServer#conn...
how EventMachine works
                   eventmachine 0.12.10
 # in lib/pr_eventmachine.rb:256
      module EventMachine
...
Table of Contents

• how Thin works
• how EventMachine works
• how AMQP works
• how Unicorn and Rainbows! works
how AMQP works

• AMQP::BasicClient
 # extend to AMQP::Client
how AMQP works

• AMQP::BasicClient
 # extend to AMQP::Client

• AMQP::Client
 # included into EventMachine::Connection
how AMQP works
        amqp 0.6.7
how AMQP works
                      amqp 0.6.7

# in lib/amqp.rb:79
# in AMQP.start
    EM.run{
      @conn ||= connect *...
how AMQP works
                      amqp 0.6.7

# in lib/amqp.rb:18
# in AMQP.connect

         Client.connect *args
how AMQP works
                           amqp 0.6.7

    # in lib/amqp/client.rb:188
    # in AMQP::Client.connect
opts =...
how Thin works
              thin 1.2.7 codename No Hup

# in lib/thin/backends/tcp_server.rb:16
# in Thin::TcpServer#conn...
how EventMachine works
                       eventmachine 0.12.10
     # in lib/eventmachine.rb:1571
     # in EventMachi...
how AMQP works
                      amqp 0.6.7

# in lib/amqp/client.rb:115
# in AMQP::Client#receive_data

   while fram...
how AMQP works

• AMQP::Frame
 # basic building block of AMQP data stream
how AMQP works

• AMQP::Frame
 # basic building block of AMQP data stream

• AMQP::Buffer
 # frame buffer and parser
how AMQP works

• AMQP::Frame
 # basic building block of AMQP data stream

• AMQP::Buffer
 # frame buffer and parser

• AM...
how AMQP works

• MQ
 # easy to use, high level wrapper
how AMQP works

• MQ
 # easy to use, high level wrapper

• MQ::Queue
 # the entities which receive messages
how AMQP works

• MQ
 # easy to use, high level wrapper

• MQ::Queue
 # the entities which receive messages

• MQ::Exchang...
how AMQP works

• MQ
 # easy to use, high level wrapper

• MQ::Queue
 # the entities which receive messages

• MQ::Exchang...
how AMQP works
# default connection
MQ.new.queue(‘name’)

# default exchange (direct)
MQ.new.publish(‘name’)

#-- convenie...
how AMQP works
MQ.queues      # all created queues
MQ.exchanges   # all created exchanges
MQ.direct      # direct exchange...
Table of Contents

• how Thin works
• how EventMachine works
• how AMQP works
• how Unicorn and Rainbows! works
Unicorn? .
Unicorn? .
• is not event-driven!
Unicorn? .
• is not event-driven!
• except Mongrel
  HTTP parser, all
  written in Ruby
Unicorn? .
• is not event-driven!
• except Mongrel
  HTTP parser, all
  written in Ruby

• yet *super fast* for
  fast cli...
Unicorn? .
• is not event-driven!
• except Mongrel
  HTTP parser, all
  written in Ruby

• yet *super fast* for
  fast cli...
Unicorn? .               Rainbows!?
• is not event-driven!
• except Mongrel
  HTTP parser, all
  written in Ruby

• yet *s...
Unicorn? .               Rainbows!?
• is not event-driven!   • could be event-driven
• except Mongrel
  HTTP parser, all
 ...
Unicorn? .               Rainbows!?
• is not event-driven!   • could be event-driven
• except Mongrel         • also pure ...
Unicorn? .               Rainbows!?
• is not event-driven!   • could be event-driven
• except Mongrel         • also pure ...
Unicorn? .               Rainbows!?
• is not event-driven!   • could be event-driven
• except Mongrel         • also pure ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel
  ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel
  ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel
  ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel
  ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel
  ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel
  ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel   ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel   ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel   ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel   ...
Unicorn? .                  Rainbows!?
• is not event-driven!
                         • RevFiberSpawn
• except Mongrel   ...
Unicorn? .             Rainbows!?
unicorn master
_ unicorn worker[0]
| _ client[0]
_ unicorn worker[1]
| _ client[1]
_ uni...
Unicorn? .             Rainbows!?
unicorn master         rainbows! master
                        _ rainbows! worker[0]
_ ...
Unicorn? .             Rainbows!?
unicorn master         rainbows! master
                        _ rainbows! worker[0]
_ ...
Unicorn? .              Rainbows!?
        static files
          |
    nginx |--> slow actions --> Rainbows!
          |
...
Unicorn? .
 http://unicorn.bogomips.org/
                                Rainbows!?
                                 http:...
how Unicorn works
         unicorn 0.97.0
how Unicorn works
                    unicorn 0.97.0

# in lib/unicorn.rb:270
# in Unicorn::HttpServer#start

         mai...
how Unicorn works
                           unicorn 0.97.0

      # in lib/unicorn.rb:602
      # in Unicorn::HttpServer#...
how Unicorn works
                           unicorn 0.97.0

      # in lib/unicorn.rb:591
      # in Unicorn::HttpServer#...
how Unicorn works
                     unicorn 0.97.0

# in lib/unicorn.rb:705
# in Unicorn::HttpServer#worker_loop

ready...
how Unicorn works
                          unicorn 0.97.0

     # in lib/unicorn.rb:630
     # in Unicorn::HttpServer#pro...
how Unicorn works
                          unicorn 0.97.0

     # in lib/unicorn/http_request.rb:31
     # in Unicorn::Ht...
how Rainbows! works
         rainbows 0.91.0
how Rainbows! works
              rainbows 0.91.0

Sorry! To be continued......
how Rainbows! works
              rainbows 0.91.0

Sorry! To be continued......


           ?
Upcoming SlideShare
Loading in...5
×

2010-04-13 Reactor Pattern & Event Driven Programming 2

3,017

Published on

Published in: Technology

Transcript of "2010-04-13 Reactor Pattern & Event Driven Programming 2"

  1. 1. Reactor Pattern & Event-Driven Programming A scalable concurrent approach, using EventMachine with Thin as an example Lin Jen-Shin, http://godfat.org/
  2. 2. Reactor Pattern & Event-Driven Programming A scalable concurrent approach, using EventMachine with Thin as an example Lin Jen-Shin, http://godfat.org/
  3. 3. Reactor Pattern & Event-Driven Programming http://godfat.org/slide/2010-04-13-reactor-pattern-and-2.pdf Lin Jen-Shin, http://godfat.org/
  4. 4. Table of Contents • concurrency, why and how in network • Event-Driven Programming explained in Flash with Ruby syntax • Reactor Pattern in EventMachine with Thin • how Thin works • how EventMachine works
  5. 5. Event-Driven Programming register method(:do_something) loop{ loop{ # you control the flow # event loop control the flow, do_something # later it calls your callback } event = pop_event_queue dispatch event if event }
  6. 6. Reactor Pattern register method(:handle) loop{ loop{ data = read data = partial_read handle data event = process data } dispatch event if event }
  7. 7. Table of Contents • how Thin works • how EventMachine works
  8. 8. Table of Contents • how Thin works • how EventMachine works
  9. 9. Table of Contents • how Thin works • how EventMachine works • how AMQP works
  10. 10. Table of Contents • how Thin works • how EventMachine works • how AMQP works • how Unicorn and Rainbows! works
  11. 11. Reactor Pattern Request (resource)
  12. 12. Reactor Pattern EventMachine Request (demultiplexer (resource) + dispatcher)
  13. 13. Reactor Pattern EventMachine Request Thin (or AMQP) (demultiplexer (resource) (request handler) + dispatcher)
  14. 14. Reactor Pattern EventMachine Request Thin (or AMQP) (demultiplexer (resource) (request handler) + dispatcher) Rack Thin handler
  15. 15. Reactor Pattern EventMachine Request Thin (or AMQP) (demultiplexer (resource) (request handler) + dispatcher) Rack Rails Rack Thin rack env adapter handler
  16. 16. Reactor Pattern EventMachine Request Thin (or AMQP) (demultiplexer (resource) (request handler) + dispatcher) Rack Rails Rack Thin Rails rack env adapter handler
  17. 17. your rails application Reactor Pattern EventMachine Request Thin (or AMQP) (demultiplexer (resource) (request handler) + dispatcher) Rack Rails Rack Thin Rails rack env adapter handler
  18. 18. how Thin works Thin (or AMQP) (request handler)
  19. 19. how Thin works • Thin::Server
  20. 20. how Thin works • Thin::Server • Thin::Backends::TcpServer # communicate with EventMachine
  21. 21. how Thin works • Thin::Server • Thin::Backends::TcpServer # communicate with EventMachine • Thin::Connection # EventMachine event handler
  22. 22. how Thin works • Thin::Server • Thin::Backends::TcpServer # communicate with EventMachine • Thin::Connection # EventMachine event handler • Thin::Request # partial HTTP request parsing # Rack env builder
  23. 23. how Thin works Thin::Server
  24. 24. how Thin works Thin::Server Backends::TcpServer
  25. 25. how Thin works Thin::Server Backends::TcpServer Connection
  26. 26. how Thin works Thin::Server Backends::TcpServer Connection Request
  27. 27. how Thin works Thin::Server Backends::TcpServer Connection Connection Request Request
  28. 28. how Thin works Thin::Server Backends::TcpServer Connection Connection Connection Request Request Request
  29. 29. how Thin works thin 1.2.7 codename No Hup
  30. 30. how Thin works thin 1.2.7 codename No Hup # in lib/thin/backends/tcp_server.rb:16 # in Thin::TcpServer#connect EventMachine.start_server( @host, @port, Thin::Connection, &method(:initialize_connection)) # rack app, backend ref, timeout, etc
  31. 31. how Thin works thin 1.2.7 codename No Hup # in lib/thin/connection.rb:42 # in Thin::Connection#receive_data process if @request.parse(data) # true: parsed, so process! # false: we need more data!
  32. 32. how Thin works thin 1.2.7 codename No Hup # in lib/thin/request.rb:82 # in Thin::Request#parse @request = @parser.execute(@env, @data, @nparsed) # @env: Rack env # @data: HTTP header buffer # @nparsed: index of parsed data
  33. 33. how Thin works thin 1.2.7 codename No Hup // in ext/thin_parser/thin.c:335 // in thin.c#Thin_HttpParser_execute thin_http_parser_execute(http, dptr, dlen, from); // http: HTTP parser pointer // dptr: HTTP header data pointer // dlen: HTTP header data length // form: previous @nparsed
  34. 34. how Thin works thin 1.2.7 codename No Hup // in ext/thin_parser/parser.rl:102 // in parser.rl#thin_http_parser_execute // (it’s mongrel’s http parser) size_t thin_http_parser_execute( http_parser *parser, const char *buffer, size_t len, size_t off)
  35. 35. how Thin works thin 1.2.7 codename No Hup Ragel is a finite state machine compiler with output support for C, C++, Objective-C, D, Java and Ruby source code.
  36. 36. how Thin works thin 1.2.7 codename No Hup Ragel is a finite state machine compiler with output support for C, C++, Objective-C, D, Java and Ruby source code. • Mongrel HTTP parser • Hpricot HTML/XML parser • JSON parser
  37. 37. how Thin works thin 1.2.7 codename No Hup # in lib/thin/connection.rb:42 # in Thin::Connection#receive_data process if @request.parse(data) # true: parsed, so process! # false: we need more data!
  38. 38. how Thin works thin 1.2.7 codename No Hup # in lib/thin/connection.rb:52 # in Thin::Connection#process if threaded? @request.threaded = true EventMachine.defer(method( :pre_process), method(:post_process)) else @request.threaded = false post_process(pre_process) end
  39. 39. how EventMachine works eventmachine 0.12.10 # in lib/eventmachine.rb:1045 # in EventMachine.defer unless @threadpool require ‘thread’ @threadpool = [] @threadqueue = ::Queue.new @resultqueue = ::Queue.new spawn_threadpool end @threadqueue << [op||blk,callback]
  40. 40. how Thin works thin 1.2.7 codename No Hup # in lib/thin/connection.rb:68 # in Thin::Connection#pre_process @request.async_callback = method(:post_process) # ... response = AsyncResponse catch(:async) do # Process the request calling the Rack adapter response = @app.call(@request.env) end response
  41. 41. how Thin works thin 1.2.7 codename No Hup # in lib/thin/connection.rb:95 # in Thin::Connection#post_process @response.status, @response.headers, @response.body = *result # ... @response.each do |chunk| trace { chunk } send_data chunk end
  42. 42. Reactor Pattern • resources • synchronous event demultiplexer • dispatcher • request handler (Thin::Connection) by wikipedia
  43. 43. Table of Contents • how Thin works • how EventMachine works • how AMQP works • how Unicorn and Rainbows! works
  44. 44. how EventMachine works eventmachine 0.12.10
  45. 45. how EventMachine works eventmachine 0.12.10 # in lib/eventmachine.rb:571 # in EventMachine.start_server s = if port start_tcp_server server, port else start_unix_server server end @acceptors[s] = [klass,args,block] # s: server (in Reactor) uuid # klass: Thin::Connection # args: [] # block: method(:initialize_connection)
  46. 46. how EventMachine works eventmachine 0.12.10 # in lib/eventmachine.rb:50 case $eventmachine_library when :pure_ruby require ‘pr_eventmachine’ when :extension require ‘rubyeventmachine’ when :java require ‘jeventmachine’
  47. 47. how EventMachine works eventmachine 0.12.10 # in lib/pr_eventmachine.rb:318 # in EventMachine.run loop { @current_loop_time = Time.now break if @stop_scheduled run_timers # timer event break if @stop_scheduled # epoll, kqueue, etc crank_selectables break if @stop_scheduled # close scheduling if client timeout run_heartbeats
  48. 48. how EventMachine works eventmachine 0.12.10 # in lib/eventmachine.rb:1445 # in EventMachine.event_callback elsif opcode == ConnectionData c = @conns[conn_binding] or raise ConnectionNotBound, “received data #{data} for unknown signature:” “#{conn_binding}” c.receive_data data elsif opcode == LoopbreakSignalled # opcode: event enum (int) # conn_binding: connection uuid # data: received data
  49. 49. how Thin works thin 1.2.7 codename No Hup # in lib/thin/connection.rb:42 # in Thin::Connection#receive_data process if @request.parse(data) # true: parsed, so process! # false: we need more data!
  50. 50. how EventMachine works eventmachine 0.12.10 # in lib/eventmachine.rb:1427 # in EventMachine.event_callback elsif opcode == ConnectionAccepted accep,args,blk = @acceptors[conn_binding] raise NoHandlerForAcceptedConnection unless accep c = accep.new data, *args @conns[data] = c blk and blk.call(c) c # (needed?) elsif opcode == ConnectionCompleted # conn_binding: server uuid # data: connection uuid
  51. 51. how Thin works thin 1.2.7 codename No Hup # in lib/thin/backends/tcp_server.rb:16 # in Thin::TcpServer#connect EventMachine.start_server( @host, @port, Thin::Connection, &method(:initialize_connection)) # rack app, backend ref, timeout, etc
  52. 52. how EventMachine works eventmachine 0.12.10 # in lib/pr_eventmachine.rb:256 module EventMachine TimerFired = 100 ConnectionData = 101 ConnectionUnbound = 102 ConnectionAccepted = 103 ConnectionCompleted = 104 LoopbreakSignalled = 105 end
  53. 53. Table of Contents • how Thin works • how EventMachine works • how AMQP works • how Unicorn and Rainbows! works
  54. 54. how AMQP works • AMQP::BasicClient # extend to AMQP::Client
  55. 55. how AMQP works • AMQP::BasicClient # extend to AMQP::Client • AMQP::Client # included into EventMachine::Connection
  56. 56. how AMQP works amqp 0.6.7
  57. 57. how AMQP works amqp 0.6.7 # in lib/amqp.rb:79 # in AMQP.start EM.run{ @conn ||= connect *args @conn.callback(&blk) if blk @conn }
  58. 58. how AMQP works amqp 0.6.7 # in lib/amqp.rb:18 # in AMQP.connect Client.connect *args
  59. 59. how AMQP works amqp 0.6.7 # in lib/amqp/client.rb:188 # in AMQP::Client.connect opts = AMQP.setting.merge(opts) EM.connect opts[:host], opts[:port], self, opts
  60. 60. how Thin works thin 1.2.7 codename No Hup # in lib/thin/backends/tcp_server.rb:16 # in Thin::TcpServer#connect EventMachine.start_server( @host, @port, Thin::Connection, &method(:initialize_connection)) # rack app, backend ref, timeout, etc
  61. 61. how EventMachine works eventmachine 0.12.10 # in lib/eventmachine.rb:1571 # in EventMachine.klass_from_handler klass = if handler and handler.is_a?(Class) raise ArgumentError, “must provide module or #{klass.name}” unless klass >= handler handler elsif handler Class.new(klass){ include handle } else klass # klass: EventMachine::Connection end # handler: Thin::Connection or AMQP::Client
  62. 62. how AMQP works amqp 0.6.7 # in lib/amqp/client.rb:115 # in AMQP::Client#receive_data while frame = Frame.parse(@buf) log ’receive’, frame process_frame frame end
  63. 63. how AMQP works • AMQP::Frame # basic building block of AMQP data stream
  64. 64. how AMQP works • AMQP::Frame # basic building block of AMQP data stream • AMQP::Buffer # frame buffer and parser
  65. 65. how AMQP works • AMQP::Frame # basic building block of AMQP data stream • AMQP::Buffer # frame buffer and parser • AMQP::Protocol::Connection # used in BasicClient#process_frame
  66. 66. how AMQP works • MQ # easy to use, high level wrapper
  67. 67. how AMQP works • MQ # easy to use, high level wrapper • MQ::Queue # the entities which receive messages
  68. 68. how AMQP works • MQ # easy to use, high level wrapper • MQ::Queue # the entities which receive messages • MQ::Exchange # the entities to which messages are sent
  69. 69. how AMQP works • MQ # easy to use, high level wrapper • MQ::Queue # the entities which receive messages • MQ::Exchange # the entities to which messages are sent by wikipedia
  70. 70. how AMQP works # default connection MQ.new.queue(‘name’) # default exchange (direct) MQ.new.publish(‘name’) #-- convenience wrapper (read: HACK) # for thread-local MQ object MQ.queue(‘name’) MQ.publish(‘name’)
  71. 71. how AMQP works MQ.queues # all created queues MQ.exchanges # all created exchanges MQ.direct # direct exchange MQ.fanout # fanout exchange MQ.topic # topic exchange MQ.headers # headers exchange
  72. 72. Table of Contents • how Thin works • how EventMachine works • how AMQP works • how Unicorn and Rainbows! works
  73. 73. Unicorn? .
  74. 74. Unicorn? . • is not event-driven!
  75. 75. Unicorn? . • is not event-driven! • except Mongrel HTTP parser, all written in Ruby
  76. 76. Unicorn? . • is not event-driven! • except Mongrel HTTP parser, all written in Ruby • yet *super fast* for fast client
  77. 77. Unicorn? . • is not event-driven! • except Mongrel HTTP parser, all written in Ruby • yet *super fast* for fast client • preforking worker with blocking I/O
  78. 78. Unicorn? . Rainbows!? • is not event-driven! • except Mongrel HTTP parser, all written in Ruby • yet *super fast* for fast client • preforking worker with blocking I/O
  79. 79. Unicorn? . Rainbows!? • is not event-driven! • could be event-driven • except Mongrel HTTP parser, all written in Ruby • yet *super fast* for fast client • preforking worker with blocking I/O
  80. 80. Unicorn? . Rainbows!? • is not event-driven! • could be event-driven • except Mongrel • also pure Ruby, HTTP parser, all except... written in Ruby • yet *super fast* for fast client • preforking worker with blocking I/O
  81. 81. Unicorn? . Rainbows!? • is not event-driven! • could be event-driven • except Mongrel • also pure Ruby, HTTP parser, all except... written in Ruby • yet *super fast* for • *any* concurrency fast client model • preforking worker with blocking I/O
  82. 82. Unicorn? . Rainbows!? • is not event-driven! • could be event-driven • except Mongrel • also pure Ruby, HTTP parser, all except... written in Ruby • yet *super fast* for • *any* concurrency fast client model • preforking worker • provide network with blocking I/O concurrency
  83. 83. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel HTTP parser, all written in Ruby • yet *super fast* for fast client • preforking worker with blocking I/O
  84. 84. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel HTTP parser, all • Revactor written in Ruby • yet *super fast* for fast client • preforking worker with blocking I/O
  85. 85. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel HTTP parser, all • Revactor written in Ruby • ThreadPool • yet *super fast* for fast client • preforking worker with blocking I/O
  86. 86. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel HTTP parser, all • Revactor written in Ruby • ThreadPool • yet *super fast* for • Rev fast client • preforking worker with blocking I/O
  87. 87. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel HTTP parser, all • Revactor written in Ruby • ThreadPool • yet *super fast* for • Rev fast client • preforking worker • ThreadSpawn with blocking I/O
  88. 88. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel HTTP parser, all • Revactor written in Ruby • ThreadPool • yet *super fast* for • Rev fast client • preforking worker • ThreadSpawn with blocking I/O • EventMachine
  89. 89. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel • RevThreadSpawn HTTP parser, all • Revactor written in Ruby • ThreadPool • yet *super fast* for • Rev fast client • preforking worker • ThreadSpawn with blocking I/O • EventMachine
  90. 90. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel • RevThreadSpawn HTTP parser, all • Revactor FiberSpawn written in Ruby • • ThreadPool • yet *super fast* for • Rev fast client • preforking worker • ThreadSpawn with blocking I/O • EventMachine
  91. 91. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel • RevThreadSpawn HTTP parser, all • Revactor FiberSpawn written in Ruby • • ThreadPool FiberPool • yet *super fast* for • fast client • Rev • preforking worker • ThreadSpawn with blocking I/O • EventMachine
  92. 92. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel • RevThreadSpawn HTTP parser, all • Revactor FiberSpawn written in Ruby • • ThreadPool FiberPool • yet *super fast* for • fast client • Rev • NeverBlock • preforking worker • ThreadSpawn with blocking I/O • EventMachine
  93. 93. Unicorn? . Rainbows!? • is not event-driven! • RevFiberSpawn • except Mongrel • RevThreadSpawn HTTP parser, all • Revactor FiberSpawn written in Ruby • • ThreadPool FiberPool • yet *super fast* for • fast client • Rev • NeverBlock • preforking worker • ThreadSpawn with blocking I/O • RevThreadPool • EventMachine
  94. 94. Unicorn? . Rainbows!? unicorn master _ unicorn worker[0] | _ client[0] _ unicorn worker[1] | _ client[1] _ unicorn worker[2] | _ client[2] ... _ unicorn worker[M] _ client[M]
  95. 95. Unicorn? . Rainbows!? unicorn master rainbows! master _ rainbows! worker[0] _ unicorn worker[0] | _ client[0,0] | _ client[0] | _ client[0,1] | ... _ unicorn worker[1] | _ client[0,N] | _ client[1] _ rainbows! worker[1] | _ client[1,0] _ unicorn worker[2] | ... | _ client[2] | _ client[1,N] ... ... _ rainbows! worker[M] _ unicorn worker[M] _ client[M,0] ... _ client[M] _ client[M,N]
  96. 96. Unicorn? . Rainbows!? unicorn master rainbows! master _ rainbows! worker[0] _ unicorn worker[0] | _ client[0,0]------ | _ client[0,1]------- ___app[0] /___app[1] | _ client[0] | _ client[0,2]-------->--< | ... __/ ... `---app[P] _ unicorn worker[1] | _ client[0,N]----/ _ rainbows! worker[1] | _ client[1] | _ client[1,0]------ | _ client[1,1]------- ___app[0] /___app[1] _ unicorn worker[2] | _ client[1,2]-------->--< | ... __/ ... `---app[P] | _ client[2] | _ client[1,N]----/ _ rainbows! worker[M] ... _ client[M,0]------ ___app[0] _ client[M,1]------- /___app[1] _ unicorn worker[M] _ client[M,2]-------->--< ... ... __/ `---app[P] _ client[M] _ client[M,N]----/
  97. 97. Unicorn? . Rainbows!? static files | nginx |--> slow actions --> Rainbows! | `--> fast actions --> Unicorn
  98. 98. Unicorn? . http://unicorn.bogomips.org/ Rainbows!? http://rainbows.rubyforge.org/ static files | nginx |--> slow actions --> Rainbows! | `--> fast actions --> Unicorn
  99. 99. how Unicorn works unicorn 0.97.0
  100. 100. how Unicorn works unicorn 0.97.0 # in lib/unicorn.rb:270 # in Unicorn::HttpServer#start maintain_worker_count
  101. 101. how Unicorn works unicorn 0.97.0 # in lib/unicorn.rb:602 # in Unicorn::HttpServer#maintain_worker_count (off = WORKER.size - worker_process) == 0 and return off < 0 and return spawn_missing_workers
  102. 102. how Unicorn works unicorn 0.97.0 # in lib/unicorn.rb:591 # in Unicorn::HttpServer#spawn_missing_workers worker = Worker.new(worker_nr, Unicorn::Util.tmpio) before_fork.call(self, worker) WORKERS[fork { ready_pipe.close if ready_pipe self.ready_pipe = nil worker_loop(worker) }] = worker
  103. 103. how Unicorn works unicorn 0.97.0 # in lib/unicorn.rb:705 # in Unicorn::HttpServer#worker_loop ready.each do |sock| begin process_client(sock.accept_nonblock) # workers load balancing here!! ^^
  104. 104. how Unicorn works unicorn 0.97.0 # in lib/unicorn.rb:630 # in Unicorn::HttpServer#process_client # read request, call app, write app response def process_client(client) client.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) response = app.call(env = REQUEST.read(client)) # [...] HttpResponse.write(client, response, HttpRequest::PARSER.headers?)
  105. 105. how Unicorn works unicorn 0.97.0 # in lib/unicorn/http_request.rb:31 # in Unicorn::HttpRequest#read # Does the majority of the IO processing. # It has been written in Ruby using about 8 # different IO processing strategies. # [...] # Anyone who thinks they can make it faster is # more than welcome to take a crack at it.
  106. 106. how Rainbows! works rainbows 0.91.0
  107. 107. how Rainbows! works rainbows 0.91.0 Sorry! To be continued......
  108. 108. how Rainbows! works rainbows 0.91.0 Sorry! To be continued...... ?
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×