1 # -*- encoding: binary -*-
3 # This module adds \Rainbows! to the
4 # {Unicorn::Configurator}[http://unicorn.bogomips.org/Unicorn/Configurator.html]
5 # \Rainbows!-specific configuration options must be inside a the Rainbows!
6 # block, otherwise Unicorn::Configurator directives may be used anwwhere
10 # use :ThreadSpawn # concurrency model to use
11 # worker_connections 400
12 # keepalive_timeout 0 # zero disables keepalives entirely
13 # client_max_body_size 5*1024*1024 # 5 megabytes
14 # keepalive_requests 666 # default:100
15 # client_header_buffer_size 2 * 1024 # 2 kilobytes
18 # # the rest of the Unicorn configuration...
20 # stderr_path "/path/to/error.log"
21 # stdout_path "/path/to/output.log"
22 module Rainbows::Configurator
23 Unicorn::Configurator::DEFAULTS.merge!({
24 :use => Rainbows::Base,
25 :worker_connections => 50,
26 :keepalive_timeout => 5,
27 :keepalive_requests => 100,
28 :client_max_body_size => 1024 * 1024,
29 :client_header_buffer_size => 1024,
30 :copy_stream => IO.respond_to?(:copy_stream) ? IO : false,
33 # Configures \Rainbows! with a given concurrency model to +use+ and
34 # a +worker_connections+ upper-bound. This method should be called
35 # inside a Unicorn/\Rainbows! configuration file.
37 # All other methods in Rainbows::Configurator must be called
40 block_given? or raise ArgumentError, "Rainbows! requires a block"
48 @block or abort "must be inside a Rainbows! block"
51 # This limits the number of connected clients per-process. The total
52 # number of clients on a server is +worker_processes+ * +worker_connections+.
54 # This option has no effect with the Base concurrency model, which is
58 def worker_connections(clients)
60 set_int(:worker_connections, clients, 1)
63 # Select a concurrency model for use with \Rainbows!. You must select
64 # this with a Symbol (prefixed with ":"). Thus if you wish to select
65 # the Rainbows::ThreadSpawn concurrency model, you would use:
71 # See the {Summary}[link:Summary.html] document for a summary of
72 # supported concurrency models. +options+ may be specified for some
73 # concurrency models, but the majority do not support them.
75 # Default: :Base (no concurrency)
76 def use(model, *options)
79 Rainbows.const_get(model)
81 warn "error loading #{model.inspect}: #{e}"
82 e.backtrace.each { |l| warn l }
83 abort "concurrency model #{model.inspect} not supported"
85 Module === mod or abort "concurrency model #{model.inspect} not supported"
89 Rainbows::O.merge!(opt)
91 Rainbows::O[opt] = true
93 abort "cannot handle option: #{opt.inspect} in #{options.inspect}"
96 mod.setup if mod.respond_to?(:setup)
100 # Sets the value (in seconds) the server will wait for a client in
101 # between requests. The default value should be enough under most
102 # conditions for browsers to render the page and start retrieving
105 # Setting this value to +0+ disables keepalive entirely
108 def keepalive_timeout(seconds)
110 set_int(:keepalive_timeout, seconds, 0)
113 # This limits the number of requests which can be made over a keep-alive
114 # connection. This is used to prevent single client from monopolizing
115 # the server and to improve fairness when load-balancing across multiple
116 # machines by forcing a client to reconnect. This may be helpful
117 # in mitigating some denial-of-service attacks.
119 # Default: 100 requests
120 def keepalive_requests(count)
124 set[:keepalive_requests] = count
126 abort "not an integer or nil: keepalive_requests=#{count.inspect}"
130 # Limits the maximum size of a request body for all requests.
131 # Setting this to +nil+ disables the maximum size check.
133 # Default: 1 megabyte (1048576 bytes)
135 # If you want endpoint-specific upload limits and use a
136 # "rack.input"-streaming concurrency model, see the Rainbows::MaxBody
137 def client_max_body_size(bytes)
139 err = "client_max_body_size must be nil or a non-negative Integer"
143 bytes >= 0 or abort err
147 set[:client_max_body_size] = bytes
150 # This governs the amount of memory allocated for an individual read(2) or
151 # recv(2) system call when reading headers. Applications that make minimal
152 # use of cookies should not increase this from the default.
154 # Rails applications using session cookies may want to increase this to
155 # 2048 bytes or more depending on expected request sizes.
157 # Increasing this will increase overall memory usage to your application,
158 # as you will need at least this amount of memory for every connected client.
160 # Default: 1024 bytes
161 def client_header_buffer_size(bytes)
163 set_int(:client_header_buffer_size, bytes, 1)
166 # Allows overriding the +klass+ where the +copy_stream+ method is
167 # used to do efficient copying of regular files, pipes, and sockets.
169 # This is only used with multi-threaded concurrency models:
173 # * WriterThreadSpawn
175 # * XEpollThreadSpawn
178 # Due to existing {bugs}[http://redmine.ruby-lang.org/search?q=copy_stream]
179 # in the Ruby IO.copy_stream implementation, \Rainbows! uses the
180 # "sendfile" RubyGem that instead of copy_stream to transfer regular files
181 # to clients. The "sendfile" RubyGem also supports more operating systems,
182 # and works with more concurrency models.
184 # Recent Linux 2.6 users may override this with "IO::Splice" from the
185 # "io_splice" RubyGem:
187 # require "io/splice"
189 # copy_stream IO::Splice
192 # Keep in mind that splice(2) itself is a relatively new system call
193 # and has been buggy in many older Linux kernels. If you're proxying
194 # the output of sockets to the client, be sure to use "io_splice"
195 # 4.1.1 or later to avoid stalling responses.
197 # Default: IO on Ruby 1.9+, false otherwise
198 def copy_stream(klass)
200 if klass && ! klass.respond_to?(:copy_stream)
201 abort "#{klass} must respond to `copy_stream' or be `false'"
203 set[:copy_stream] = klass
208 # inject the Rainbows! method into Unicorn::Configurator
209 Unicorn::Configurator.__send__(:include, Rainbows::Configurator)