refactor graceful shutdowns again, harder
[rainbows.git] / lib / rainbows.rb
blob096f7001ff74b441cbf649e24065e9d019276432
1 # -*- encoding: binary -*-
2 require 'unicorn'
4 module Rainbows
6   # global vars because class/instance variables are confusing me :<
7   # this struct is only accessed inside workers and thus private to each
8   G = Struct.new(:cur, :max, :logger, :alive, :app).new
9   # G.cur may not be used the network concurrency model
10   G.alive = true
12   require 'rainbows/const'
13   require 'rainbows/http_server'
14   require 'rainbows/http_response'
15   require 'rainbows/base'
16   autoload :AppPool, 'rainbows/app_pool'
18   class << self
20     # runs the Rainbows! HttpServer with +app+ and +options+ and does
21     # not return until the server has exited.
22     def run(app, options = {})
23       HttpServer.new(app, options).start.join
24     end
25   end
27   # configures \Rainbows! with a given concurrency model to +use+ and
28   # a +worker_connections+ upper-bound.  This method may be called
29   # inside a Unicorn/Rainbows configuration file:
30   #
31   #   Rainbows! do
32   #     use :Revactor # this may also be :ThreadSpawn or :ThreadPool
33   #     worker_connections 400
34   #   end
35   #
36   #   # the rest of the Unicorn configuration
37   #   worker_processes 8
38   #
39   # See the documentation for the respective Revactor, ThreadSpawn,
40   # and ThreadPool classes for descriptions and recommendations for
41   # each of them.  The total number of clients we're able to serve is
42   # +worker_processes+ * +worker_connections+, so in the above example
43   # we can serve 8 * 400 = 3200 clients concurrently.
44   def Rainbows!(&block)
45     block_given? or raise ArgumentError, "Rainbows! requires a block"
46     HttpServer.setup(block)
47   end
49   # maps models to default worker counts, default worker count numbers are
50   # pretty arbitrary and tuning them to your application and hardware is
51   # highly recommended
52   MODEL_WORKER_CONNECTIONS = {
53     :Base => 1, # this one can't change
54     :Revactor => 50,
55     :ThreadSpawn => 30,
56     :ThreadPool => 10,
57     :Rev => 50,
58   }.each do |model, _|
59     u = model.to_s.gsub(/([a-z0-9])([A-Z0-9])/) { "#{$1}_#{$2.downcase!}" }
60     autoload model, "rainbows/#{u.downcase!}"
61   end
63 end
65 # inject the Rainbows! method into Unicorn::Configurator
66 Unicorn::Configurator.class_eval { include Rainbows }