tests: "wc -c" portability for *BSDs
[rainbows.git] / lib / rainbows / fiber_pool.rb
blob07a9faf161e0b95364f29feba1b6cd9a594f6aec
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.
8 # This concurrency model is difficult to use with existing applications,
9 # lacks third-party support, and is thus NOT recommended.
11 # The pool size is equal to the number of +worker_connections+.
12 # Compared to the ThreadPool model, Fibers are very cheap in terms of
13 # memory usage so you can have more active connections.  This model
14 # supports a streaming "rack.input" with lightweight concurrency.
15 # Applications are strongly advised to wrap all slow IO objects
16 # (sockets, pipes) using the Rainbows::Fiber::IO class whenever
17 # possible.
18 module Rainbows::FiberPool
19   include Rainbows::Fiber::Base
21   def worker_loop(worker) # :nodoc:
22     init_worker_process(worker)
23     pool = []
24     worker_connections.times {
25       Fiber.new {
26         process(Fiber.yield) while pool << Fiber.current
27       }.resume # resume to hit Fiber.yield so it waits on a client
28     }
29     Rainbows::Fiber::Base.setup(self.class, app)
31     begin
32       schedule do |l|
33         fib = pool.pop or break # let another worker process take it
34         if io = l.kgio_tryaccept
35           fib.resume(io)
36         else
37           pool << fib
38         end
39       end
40     rescue => e
41       Rainbows::Error.listen_loop(e)
42     end while Rainbows.cur_alive
43   end
44 end