1 # -*- encoding: binary -*-
3 # This module adds \Rainbows! to the
4 # {Unicorn::Configurator}[https://yhbt.net/unicorn/Unicorn/Configurator.html]
5 # \Rainbows!-specific configuration options must be inside a the Rainbows!
6 # block, otherwise Unicorn::Configurator directives may be used anywhere
9 # Warning: The "timeout" directive in unicorn is far more dangerous
10 # in Rainbows!, since ALL requests running on a process will be lost
11 # on worker death, not just one. Instead, handle application-level
12 # timeouts yourself: https://yhbt.net/unicorn/Application_Timeouts.html
15 # use :ThreadSpawn # concurrency model to use
16 # worker_connections 400
17 # keepalive_timeout 0 # zero disables keepalives entirely
18 # client_max_body_size 5*1024*1024 # 5 megabytes
19 # keepalive_requests 666 # default:100
20 # client_header_buffer_size 2 * 1024 # 2 kilobytes
23 # # the rest of the Unicorn configuration...
25 # stderr_path "/path/to/error.log"
26 # stdout_path "/path/to/output.log"
27 module Rainbows::Configurator
28 Unicorn::Configurator::DEFAULTS.merge!({
30 worker_connections: 50,
32 keepalive_requests: 100,
33 client_max_body_size: 1024 * 1024,
34 client_header_buffer_size: 1024,
35 client_max_header_size: 112 * 1024,
39 # Configures \Rainbows! with a given concurrency model to +use+ and
40 # a +worker_connections+ upper-bound. This method should be called
41 # inside a Unicorn/\Rainbows! configuration file.
43 # All other methods in Rainbows::Configurator must be called
46 block_given? or raise ArgumentError, "Rainbows! requires a block"
54 @block or abort "must be inside a Rainbows! block"
57 # This limits the number of connected clients per-process. The total
58 # number of clients on a server is +worker_processes+ * +worker_connections+.
60 # This option has no effect with the Base concurrency model, which is
64 def worker_connections(clients)
66 set_int(:worker_connections, clients, 1)
69 # Select a concurrency model for use with \Rainbows!. You must select
70 # this with a Symbol (prefixed with ":"). Thus if you wish to select
71 # the Rainbows::ThreadSpawn concurrency model, you would use:
77 # See the {Summary}[link:Summary.html] document for a summary of
78 # supported concurrency models. +options+ may be specified for some
79 # concurrency models, but the majority do not support them.
81 # Default: :Base (no concurrency)
82 def use(model, *options)
85 Rainbows.const_get(model)
87 warn "error loading #{model.inspect}: #{e}"
88 e.backtrace.each { |l| warn l }
89 abort "concurrency model #{model.inspect} not supported"
91 Module === mod or abort "concurrency model #{model.inspect} not supported"
95 Rainbows::O.merge!(opt)
97 Rainbows::O[opt] = true
99 abort "cannot handle option: #{opt.inspect} in #{options.inspect}"
102 mod.setup if mod.respond_to?(:setup)
106 # Sets the value (in seconds) the server will wait for a client in
107 # between requests. The default value should be enough under most
108 # conditions for browsers to render the page and start retrieving
111 # Setting this value to +0+ disables keepalive entirely
114 def keepalive_timeout(seconds)
116 set_int(:keepalive_timeout, seconds, 0)
119 # This limits the number of requests which can be made over a keep-alive
120 # connection. This is used to prevent single client from monopolizing
121 # the server and to improve fairness when load-balancing across multiple
122 # machines by forcing a client to reconnect. This may be helpful
123 # in mitigating some denial-of-service attacks.
125 # Default: 100 requests
126 def keepalive_requests(count)
130 set[:keepalive_requests] = count
132 abort "not an integer or nil: keepalive_requests=#{count.inspect}"
136 # Limits the maximum size of a request body for all requests.
137 # Setting this to +nil+ disables the maximum size check.
139 # Default: 1 megabyte (1048576 bytes)
141 # If you want endpoint-specific upload limits and use a
142 # "rack.input"-streaming concurrency model, see the Rainbows::MaxBody
143 def client_max_body_size(bytes)
145 err = "client_max_body_size must be nil or a non-negative Integer"
149 bytes >= 0 or abort err
153 set[:client_max_body_size] = bytes
156 # Limits the maximum size of a request header for all requests.
158 # Default: 112 kilobytes (114688 bytes)
160 # Lowering this will lower worst-case memory usage and mitigate some
161 # denial-of-service attacks. This should be larger than
162 # client_header_buffer_size.
163 def client_max_header_size(bytes)
165 set_int(:client_max_header_size, bytes, 8)
168 # This governs the amount of memory allocated for an individual read(2) or
169 # recv(2) system call when reading headers. Applications that make minimal
170 # use of cookies should not increase this from the default.
172 # Rails applications using session cookies may want to increase this to
173 # 2048 bytes or more depending on expected request sizes.
175 # Increasing this will increase overall memory usage to your application,
176 # as you will need at least this amount of memory for every connected client.
178 # Default: 1024 bytes
179 def client_header_buffer_size(bytes)
181 set_int(:client_header_buffer_size, bytes, 1)
184 # Allows overriding the +klass+ where the +copy_stream+ method is
185 # used to do efficient copying of regular files, pipes, and sockets.
187 # This is only used with multi-threaded concurrency models:
191 # * WriterThreadSpawn
193 # * XEpollThreadSpawn
196 # Due to existing {bugs}[http://redmine.ruby-lang.org/search?q=copy_stream]
197 # in the Ruby IO.copy_stream implementation, \Rainbows! uses the
198 # "sendfile" RubyGem that instead of copy_stream to transfer regular files
199 # to clients. The "sendfile" RubyGem also supports more operating systems,
200 # and works with more concurrency models.
202 # Recent Linux 2.6 users may override this with "IO::Splice" from the
203 # "io_splice" RubyGem:
205 # require "io/splice"
207 # copy_stream IO::Splice
210 # Keep in mind that splice(2) itself is a relatively new system call
211 # and has been buggy in many older Linux kernels. If you're proxying
212 # the output of sockets to the client, be sure to use "io_splice"
213 # 4.1.1 or later to avoid stalling responses.
215 # Default: IO on Ruby 1.9+, false otherwise
216 def copy_stream(klass)
218 if klass && ! klass.respond_to?(:copy_stream)
219 abort "#{klass} must respond to `copy_stream' or be `false'"
221 set[:copy_stream] = klass
226 # inject the Rainbows! method into Unicorn::Configurator
227 Unicorn::Configurator.__send__(:include, Rainbows::Configurator)