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