common Rainbows.accept method
[rainbows.git] / lib / rainbows / fiber_pool.rb
blob2a1c5f7b38110c55d1a68045e1ec8791252e983f
1 # -*- encoding: binary -*-
2 require 'rainbows/fiber'
4 module Rainbows
6   # A Fiber-based concurrency model for Ruby 1.9.  This uses a pool of
7   # Fibers to handle client IO to run the application and the root Fiber
8   # for scheduling and connection acceptance.  The pool size is equal to
9   # the number of +worker_connections+.  Compared to the ThreadPool
10   # model, Fibers are very cheap in terms of memory usage so you can
11   # have more active connections.  This model supports a streaming
12   # "rack.input" with lightweight concurrency.  Applications are
13   # strongly advised to wrap all slow IO objects (sockets, pipes) using
14   # the Rainbows::Fiber::IO class whenever possible.
16   module FiberPool
17     include Fiber::Base
19     def worker_loop(worker)
20       init_worker_process(worker)
21       pool = []
22       worker_connections.times {
23         ::Fiber.new {
24           process_client(::Fiber.yield) while pool << ::Fiber.current
25         }.resume # resume to hit ::Fiber.yield so it waits on a client
26       }
27       Fiber::Base.const_set(:APP, app)
29       begin
30         schedule do |l|
31           fib = pool.shift or break # let another worker process take it
32           if io = Rainbows.accept(l)
33             fib.resume(Fiber::IO.new(io, fib))
34           else
35             pool << fib
36           end
37         end
38       rescue => e
39         Error.listen_loop(e)
40       end while G.alive || G.cur > 0
41     end
43   end
44 end