puma 3.6.0 → 3.12.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/{History.txt → History.md} +293 -79
- data/README.md +143 -227
- data/docs/architecture.md +36 -0
- data/{DEPLOYMENT.md → docs/deployment.md} +0 -0
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/docs/plugins.md +28 -0
- data/docs/restart.md +39 -0
- data/docs/signals.md +56 -3
- data/docs/systemd.md +124 -22
- data/ext/puma_http11/extconf.rb +2 -0
- data/ext/puma_http11/http11_parser.c +85 -84
- data/ext/puma_http11/http11_parser.h +1 -0
- data/ext/puma_http11/http11_parser.rl +10 -9
- data/ext/puma_http11/io_buffer.c +7 -7
- data/ext/puma_http11/mini_ssl.c +62 -6
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +13 -16
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +15 -2
- data/ext/puma_http11/puma_http11.c +1 -0
- data/lib/puma.rb +13 -5
- data/lib/puma/app/status.rb +8 -0
- data/lib/puma/binder.rb +21 -14
- data/lib/puma/cli.rb +49 -33
- data/lib/puma/client.rb +39 -4
- data/lib/puma/cluster.rb +51 -11
- data/lib/puma/commonlogger.rb +19 -20
- data/lib/puma/compat.rb +3 -7
- data/lib/puma/configuration.rb +133 -130
- data/lib/puma/const.rb +13 -37
- data/lib/puma/control_cli.rb +38 -35
- data/lib/puma/convenient.rb +3 -3
- data/lib/puma/detect.rb +3 -1
- data/lib/puma/dsl.rb +80 -58
- data/lib/puma/events.rb +6 -8
- data/lib/puma/io_buffer.rb +1 -1
- data/lib/puma/jruby_restart.rb +0 -1
- data/lib/puma/launcher.rb +52 -30
- data/lib/puma/minissl.rb +73 -4
- data/lib/puma/null_io.rb +6 -13
- data/lib/puma/plugin/tmp_restart.rb +1 -2
- data/lib/puma/rack/builder.rb +3 -0
- data/lib/puma/rack/urlmap.rb +9 -8
- data/lib/puma/reactor.rb +135 -0
- data/lib/puma/runner.rb +23 -1
- data/lib/puma/server.rb +117 -34
- data/lib/puma/single.rb +14 -3
- data/lib/puma/thread_pool.rb +67 -20
- data/lib/puma/util.rb +1 -5
- data/lib/rack/handler/puma.rb +58 -17
- data/tools/jungle/README.md +12 -2
- data/tools/jungle/init.d/README.md +9 -2
- data/tools/jungle/init.d/puma +32 -62
- data/tools/jungle/init.d/run-puma +5 -1
- data/tools/jungle/rc.d/README.md +74 -0
- data/tools/jungle/rc.d/puma +61 -0
- data/tools/jungle/rc.d/puma.conf +10 -0
- data/tools/trickletest.rb +1 -1
- metadata +22 -92
- data/Gemfile +0 -13
- data/Manifest.txt +0 -77
- data/Rakefile +0 -158
- data/lib/puma/rack/backports/uri/common_18.rb +0 -59
- data/lib/puma/rack/backports/uri/common_192.rb +0 -55
- data/puma.gemspec +0 -52
data/lib/puma/const.rb
CHANGED
@@ -53,6 +53,8 @@ module Puma
|
|
53
53
|
415 => 'Unsupported Media Type',
|
54
54
|
416 => 'Range Not Satisfiable',
|
55
55
|
417 => 'Expectation Failed',
|
56
|
+
418 => 'I\'m A Teapot',
|
57
|
+
421 => 'Misdirected Request',
|
56
58
|
422 => 'Unprocessable Entity',
|
57
59
|
423 => 'Locked',
|
58
60
|
424 => 'Failed Dependency',
|
@@ -60,6 +62,7 @@ module Puma
|
|
60
62
|
428 => 'Precondition Required',
|
61
63
|
429 => 'Too Many Requests',
|
62
64
|
431 => 'Request Header Fields Too Large',
|
65
|
+
451 => 'Unavailable For Legal Reasons',
|
63
66
|
500 => 'Internal Server Error',
|
64
67
|
501 => 'Not Implemented',
|
65
68
|
502 => 'Bad Gateway',
|
@@ -73,19 +76,14 @@ module Puma
|
|
73
76
|
511 => 'Network Authentication Required'
|
74
77
|
}
|
75
78
|
|
76
|
-
SYMBOL_TO_STATUS_CODE = Hash[*HTTP_STATUS_CODES.map { |code, message|
|
77
|
-
[message.downcase.gsub(/\s|-|'/, '_').to_sym, code]
|
78
|
-
}.flatten]
|
79
|
-
|
80
79
|
# For some HTTP status codes the client only expects headers.
|
81
80
|
#
|
82
81
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
STATUS_WITH_NO_ENTITY_BODY = no_body
|
82
|
+
STATUS_WITH_NO_ENTITY_BODY = {
|
83
|
+
204 => true,
|
84
|
+
205 => true,
|
85
|
+
304 => true
|
86
|
+
}
|
89
87
|
|
90
88
|
# Frequently used constants when constructing requests or responses. Many times
|
91
89
|
# the constant just refers to a string with the same contents. Using these constants
|
@@ -100,10 +98,10 @@ module Puma
|
|
100
98
|
# too taxing on performance.
|
101
99
|
module Const
|
102
100
|
|
103
|
-
PUMA_VERSION = VERSION = "3.
|
104
|
-
CODE_NAME = "
|
101
|
+
PUMA_VERSION = VERSION = "3.12.0".freeze
|
102
|
+
CODE_NAME = "Llamas in Pajamas".freeze
|
105
103
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
106
|
-
|
104
|
+
|
107
105
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
108
106
|
|
109
107
|
# The default number of seconds for another request within a persistent
|
@@ -118,15 +116,6 @@ module Puma
|
|
118
116
|
# sending data back
|
119
117
|
WRITE_TIMEOUT = 10
|
120
118
|
|
121
|
-
# How long, after raising the ForceShutdown of a thread during
|
122
|
-
# forced shutdown mode, to wait for the thread to try and finish
|
123
|
-
# up it's work before leaving the thread to die on the vine.
|
124
|
-
SHUTDOWN_GRACE_TIME = 5 # seconds
|
125
|
-
|
126
|
-
DATE = "Date".freeze
|
127
|
-
|
128
|
-
SCRIPT_NAME = "SCRIPT_NAME".freeze
|
129
|
-
|
130
119
|
# The original URI requested by the client.
|
131
120
|
REQUEST_URI= 'REQUEST_URI'.freeze
|
132
121
|
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
@@ -163,26 +152,12 @@ module Puma
|
|
163
152
|
# Maximum request body size before it is moved out of memory and into a tempfile for reading.
|
164
153
|
MAX_BODY = MAX_HEADER
|
165
154
|
|
166
|
-
# A frozen format for this is about 15% faster
|
167
|
-
STATUS_FORMAT = "HTTP/1.1 %d %s\r\nConnection: close\r\n".freeze
|
168
|
-
|
169
|
-
CONTENT_TYPE = "Content-Type".freeze
|
170
|
-
|
171
|
-
LAST_MODIFIED = "Last-Modified".freeze
|
172
|
-
ETAG = "ETag".freeze
|
173
|
-
SLASH = "/".freeze
|
174
155
|
REQUEST_METHOD = "REQUEST_METHOD".freeze
|
175
|
-
GET = "GET".freeze
|
176
156
|
HEAD = "HEAD".freeze
|
177
157
|
# ETag is based on the apache standard of hex mtime-size-inode (inode is 0 on win32)
|
178
|
-
ETAG_FORMAT = "\"%x-%x-%x\"".freeze
|
179
158
|
LINE_END = "\r\n".freeze
|
180
159
|
REMOTE_ADDR = "REMOTE_ADDR".freeze
|
181
160
|
HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR".freeze
|
182
|
-
HTTP_IF_MODIFIED_SINCE = "HTTP_IF_MODIFIED_SINCE".freeze
|
183
|
-
HTTP_IF_NONE_MATCH = "HTTP_IF_NONE_MATCH".freeze
|
184
|
-
REDIRECT = "HTTP/1.1 302 Found\r\nLocation: %s\r\nConnection: close\r\n\r\n".freeze
|
185
|
-
HOST = "HOST".freeze
|
186
161
|
|
187
162
|
SERVER_NAME = "SERVER_NAME".freeze
|
188
163
|
SERVER_PORT = "SERVER_PORT".freeze
|
@@ -195,7 +170,6 @@ module Puma
|
|
195
170
|
|
196
171
|
SERVER_PROTOCOL = "SERVER_PROTOCOL".freeze
|
197
172
|
HTTP_11 = "HTTP/1.1".freeze
|
198
|
-
HTTP_10 = "HTTP/1.0".freeze
|
199
173
|
|
200
174
|
SERVER_SOFTWARE = "SERVER_SOFTWARE".freeze
|
201
175
|
GATEWAY_INTERFACE = "GATEWAY_INTERFACE".freeze
|
@@ -249,5 +223,7 @@ module Puma
|
|
249
223
|
HIJACK_P = "rack.hijack?".freeze
|
250
224
|
HIJACK = "rack.hijack".freeze
|
251
225
|
HIJACK_IO = "rack.hijack_io".freeze
|
226
|
+
|
227
|
+
EARLY_HINTS = "rack.early_hints".freeze
|
252
228
|
end
|
253
229
|
end
|
data/lib/puma/control_cli.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'optparse'
|
2
|
-
require 'puma'
|
2
|
+
require 'puma/state_file'
|
3
3
|
require 'puma/const'
|
4
4
|
require 'puma/detect'
|
5
5
|
require 'puma/configuration'
|
@@ -9,7 +9,7 @@ require 'socket'
|
|
9
9
|
module Puma
|
10
10
|
class ControlCLI
|
11
11
|
|
12
|
-
COMMANDS = %w{halt restart phased-restart start stats status stop reload-worker-directory}
|
12
|
+
COMMANDS = %w{halt restart phased-restart start stats status stop reload-worker-directory gc gc-stats}
|
13
13
|
|
14
14
|
def initialize(argv, stdout=STDOUT, stderr=STDERR)
|
15
15
|
@state = nil
|
@@ -69,6 +69,7 @@ module Puma
|
|
69
69
|
end
|
70
70
|
|
71
71
|
opts.order!(argv) { |a| opts.terminate a }
|
72
|
+
opts.parse!
|
72
73
|
|
73
74
|
@command = argv.shift
|
74
75
|
|
@@ -78,11 +79,12 @@ module Puma
|
|
78
79
|
end
|
79
80
|
|
80
81
|
if @config_file
|
81
|
-
config = Puma::Configuration.
|
82
|
-
|
83
|
-
@
|
82
|
+
config = Puma::Configuration.new({ config_files: [@config_file] }, {})
|
83
|
+
config.load
|
84
|
+
@state ||= config.options[:state]
|
85
|
+
@control_url ||= config.options[:control_url]
|
84
86
|
@control_auth_token ||= config.options[:control_auth_token]
|
85
|
-
@pidfile
|
87
|
+
@pidfile ||= config.options[:pidfile]
|
86
88
|
end
|
87
89
|
end
|
88
90
|
|
@@ -97,6 +99,7 @@ module Puma
|
|
97
99
|
|
98
100
|
rescue => e
|
99
101
|
@stdout.puts e.message
|
102
|
+
@stdout.puts e.backtrace
|
100
103
|
exit 1
|
101
104
|
end
|
102
105
|
|
@@ -167,7 +170,7 @@ module Puma
|
|
167
170
|
end
|
168
171
|
|
169
172
|
message "Command #{@command} sent success"
|
170
|
-
message response.last if @command == "stats"
|
173
|
+
message response.last if @command == "stats" || @command == "gc-stats"
|
171
174
|
end
|
172
175
|
|
173
176
|
@server.close
|
@@ -179,46 +182,45 @@ module Puma
|
|
179
182
|
end
|
180
183
|
|
181
184
|
begin
|
182
|
-
Process.getpgid @pid
|
183
|
-
rescue SystemCallError
|
184
|
-
if @command == "restart"
|
185
|
-
start
|
186
|
-
else
|
187
|
-
raise "No pid '#{@pid}' found"
|
188
|
-
end
|
189
|
-
end
|
190
185
|
|
191
|
-
|
192
|
-
|
193
|
-
|
186
|
+
case @command
|
187
|
+
when "restart"
|
188
|
+
Process.kill "SIGUSR2", @pid
|
194
189
|
|
195
|
-
|
196
|
-
|
190
|
+
when "halt"
|
191
|
+
Process.kill "QUIT", @pid
|
197
192
|
|
198
|
-
|
199
|
-
|
193
|
+
when "stop"
|
194
|
+
Process.kill "SIGTERM", @pid
|
200
195
|
|
201
|
-
|
202
|
-
|
203
|
-
|
196
|
+
when "stats"
|
197
|
+
puts "Stats not available via pid only"
|
198
|
+
return
|
204
199
|
|
205
|
-
|
206
|
-
|
207
|
-
|
200
|
+
when "reload-worker-directory"
|
201
|
+
puts "reload-worker-directory not available via pid only"
|
202
|
+
return
|
208
203
|
|
209
|
-
|
210
|
-
|
204
|
+
when "phased-restart"
|
205
|
+
Process.kill "SIGUSR1", @pid
|
211
206
|
|
212
|
-
|
213
|
-
|
214
|
-
|
207
|
+
else
|
208
|
+
return
|
209
|
+
end
|
210
|
+
|
211
|
+
rescue SystemCallError
|
212
|
+
if @command == "restart"
|
213
|
+
start
|
214
|
+
else
|
215
|
+
raise "No pid '#{@pid}' found"
|
216
|
+
end
|
215
217
|
end
|
216
218
|
|
217
219
|
message "Command #{@command} sent success"
|
218
220
|
end
|
219
221
|
|
220
222
|
def run
|
221
|
-
start if @command == "start"
|
223
|
+
return start if @command == "start"
|
222
224
|
|
223
225
|
prepare_configuration
|
224
226
|
|
@@ -230,6 +232,7 @@ module Puma
|
|
230
232
|
|
231
233
|
rescue => e
|
232
234
|
message e.message
|
235
|
+
message e.backtrace
|
233
236
|
exit 1
|
234
237
|
end
|
235
238
|
|
@@ -242,7 +245,7 @@ module Puma
|
|
242
245
|
run_args += ["-S", @state] if @state
|
243
246
|
run_args += ["-q"] if @quiet
|
244
247
|
run_args += ["--pidfile", @pidfile] if @pidfile
|
245
|
-
run_args += ["--control", @control_url] if @control_url
|
248
|
+
run_args += ["--control-url", @control_url] if @control_url
|
246
249
|
run_args += ["--control-token", @control_auth_token] if @control_auth_token
|
247
250
|
run_args += ["-C", @config_file] if @config_file
|
248
251
|
|
data/lib/puma/convenient.rb
CHANGED
@@ -3,12 +3,12 @@ require 'puma/configuration'
|
|
3
3
|
|
4
4
|
module Puma
|
5
5
|
def self.run(opts={})
|
6
|
-
cfg = Puma::Configuration.new do |
|
6
|
+
cfg = Puma::Configuration.new do |user_config|
|
7
7
|
if port = opts[:port]
|
8
|
-
|
8
|
+
user_config.port port
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
user_config.quiet
|
12
12
|
|
13
13
|
yield c
|
14
14
|
end
|
data/lib/puma/detect.rb
CHANGED
data/lib/puma/dsl.rb
CHANGED
@@ -1,20 +1,35 @@
|
|
1
1
|
module Puma
|
2
2
|
# The methods that are available for use inside the config file.
|
3
|
+
# These same methods are used in Puma cli and the rack handler
|
4
|
+
# internally.
|
3
5
|
#
|
6
|
+
# Used manually (via CLI class):
|
7
|
+
#
|
8
|
+
# config = Configuration.new({}) do |user_config|
|
9
|
+
# user_config.port 3001
|
10
|
+
# end
|
11
|
+
# config.load
|
12
|
+
#
|
13
|
+
# puts config.options[:binds]
|
14
|
+
# "tcp://127.0.0.1:3001"
|
15
|
+
#
|
16
|
+
# Used to load file:
|
17
|
+
#
|
18
|
+
# $ cat puma_config.rb
|
19
|
+
# port 3002
|
20
|
+
#
|
21
|
+
# config = Configuration.new(config_file: "puma_config.rb")
|
22
|
+
# config.load
|
23
|
+
#
|
24
|
+
# puts config.options[:binds]
|
25
|
+
# # => "tcp://127.0.0.1:3002"
|
26
|
+
#
|
27
|
+
# Detailed docs can be found in `examples/config.rb`
|
4
28
|
class DSL
|
5
29
|
include ConfigDefault
|
6
30
|
|
7
|
-
def self.load(options, cfg, path)
|
8
|
-
d = new(options, cfg)
|
9
|
-
d._load_from(path)
|
10
|
-
|
11
|
-
options
|
12
|
-
ensure
|
13
|
-
d._offer_plugins
|
14
|
-
end
|
15
|
-
|
16
31
|
def initialize(options, config)
|
17
|
-
@config
|
32
|
+
@config = config
|
18
33
|
@options = options
|
19
34
|
|
20
35
|
@plugins = []
|
@@ -40,36 +55,10 @@ module Puma
|
|
40
55
|
@plugins.clear
|
41
56
|
end
|
42
57
|
|
43
|
-
def _run(&blk)
|
44
|
-
blk.call self
|
45
|
-
ensure
|
46
|
-
_offer_plugins
|
47
|
-
end
|
48
|
-
|
49
58
|
def inject(&blk)
|
50
59
|
instance_eval(&blk)
|
51
60
|
end
|
52
61
|
|
53
|
-
# Load configuration from another named file. If the file name is absolute,
|
54
|
-
# load the file as an absolute path. Otherwise load it relative to the
|
55
|
-
# current config file.
|
56
|
-
#
|
57
|
-
def import(file)
|
58
|
-
if File.extname(file) == ""
|
59
|
-
file += ".rb"
|
60
|
-
end
|
61
|
-
|
62
|
-
if file[0,1] == "/"
|
63
|
-
path = file
|
64
|
-
elsif @path
|
65
|
-
path = File.join File.dirname(@path), file
|
66
|
-
else
|
67
|
-
raise "No original configuration path to import relative to"
|
68
|
-
end
|
69
|
-
|
70
|
-
DSL.new(@options, @config)._load_from(path)
|
71
|
-
end
|
72
|
-
|
73
62
|
def get(key,default=nil)
|
74
63
|
@options[key.to_sym] || default
|
75
64
|
end
|
@@ -115,15 +104,35 @@ module Puma
|
|
115
104
|
end
|
116
105
|
|
117
106
|
# Load additional configuration from a file
|
107
|
+
# Files get loaded later via Configuration#load
|
118
108
|
def load(file)
|
119
|
-
|
109
|
+
@options[:config_files] ||= []
|
110
|
+
@options[:config_files] << file
|
120
111
|
end
|
121
112
|
|
122
|
-
#
|
123
|
-
# protocols.
|
113
|
+
# Adds a binding for the server to +url+. tcp://, unix://, and ssl:// are the only accepted
|
114
|
+
# protocols. Use query parameters within the url to specify options.
|
115
|
+
#
|
116
|
+
# @note multiple urls can be bound to, calling `bind` does not overwrite previous bindings.
|
124
117
|
#
|
118
|
+
# @example Explicitly the socket backlog depth (default is 1024)
|
119
|
+
# bind('unix:///var/run/puma.sock?backlog=2048')
|
120
|
+
#
|
121
|
+
# @example Set up ssl cert
|
122
|
+
# bind('ssl://127.0.0.1:9292?key=key.key&cert=cert.pem')
|
123
|
+
#
|
124
|
+
# @example Prefer low-latency over higher throughput (via `Socket::TCP_NODELAY`)
|
125
|
+
# bind('tcp://0.0.0.0:9292?low_latency=true')
|
126
|
+
#
|
127
|
+
# @example Set socket permissions
|
128
|
+
# bind('unix:///var/run/puma.sock?umask=0111')
|
125
129
|
def bind(url)
|
126
|
-
|
130
|
+
@options[:binds] ||= []
|
131
|
+
@options[:binds] << url
|
132
|
+
end
|
133
|
+
|
134
|
+
def clear_binds!
|
135
|
+
@options[:binds] = []
|
127
136
|
end
|
128
137
|
|
129
138
|
# Define the TCP port to bind to. Use +bind+ for more advanced options.
|
@@ -137,7 +146,13 @@ module Puma
|
|
137
146
|
# them
|
138
147
|
#
|
139
148
|
def persistent_timeout(seconds)
|
140
|
-
@options[:persistent_timeout] = seconds
|
149
|
+
@options[:persistent_timeout] = Integer(seconds)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Define how long the tcp socket stays open, if no data has been received
|
153
|
+
#
|
154
|
+
def first_data_timeout(seconds)
|
155
|
+
@options[:first_data_timeout] = Integer(seconds)
|
141
156
|
end
|
142
157
|
|
143
158
|
# Work around leaky apps that leave garbage in Thread locals
|
@@ -154,7 +169,7 @@ module Puma
|
|
154
169
|
end
|
155
170
|
|
156
171
|
# When shutting down, drain the accept socket of pending
|
157
|
-
# connections and
|
172
|
+
# connections and process them. This loops over the accept
|
158
173
|
# socket until there are no more read events and then stops
|
159
174
|
# looking and waits for the requests to finish.
|
160
175
|
def drain_on_shutdown(which=true)
|
@@ -192,7 +207,8 @@ module Puma
|
|
192
207
|
# This can be called multiple times to add code each time.
|
193
208
|
#
|
194
209
|
def on_restart(&block)
|
195
|
-
|
210
|
+
@options[:on_restart] ||= []
|
211
|
+
@options[:on_restart] << block
|
196
212
|
end
|
197
213
|
|
198
214
|
# Command to use to restart puma. This should be just how to
|
@@ -238,6 +254,10 @@ module Puma
|
|
238
254
|
@options[:mode] = :tcp
|
239
255
|
end
|
240
256
|
|
257
|
+
def early_hints(answer=true)
|
258
|
+
@options[:early_hints] = answer
|
259
|
+
end
|
260
|
+
|
241
261
|
# Redirect STDOUT and STDERR to files specified.
|
242
262
|
def stdout_redirect(stdout=nil, stderr=nil, append=false)
|
243
263
|
@options[:redirect_stdout] = stdout
|
@@ -264,11 +284,13 @@ module Puma
|
|
264
284
|
end
|
265
285
|
|
266
286
|
def ssl_bind(host, port, opts)
|
287
|
+
verify = opts.fetch(:verify_mode, 'none')
|
288
|
+
|
267
289
|
if defined?(JRUBY_VERSION)
|
268
290
|
keystore_additions = "keystore=#{opts[:keystore]}&keystore-pass=#{opts[:keystore_pass]}"
|
269
|
-
bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}&#{keystore_additions}&verify_mode=#{
|
291
|
+
bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}&#{keystore_additions}&verify_mode=#{verify}"
|
270
292
|
else
|
271
|
-
bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}&verify_mode=#{
|
293
|
+
bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}&verify_mode=#{verify}"
|
272
294
|
end
|
273
295
|
end
|
274
296
|
|
@@ -295,7 +317,8 @@ module Puma
|
|
295
317
|
# This can be called multiple times to add hooks.
|
296
318
|
#
|
297
319
|
def before_fork(&block)
|
298
|
-
|
320
|
+
@options[:before_fork] ||= []
|
321
|
+
@options[:before_fork] << block
|
299
322
|
end
|
300
323
|
|
301
324
|
# *Cluster mode only* Code to run in a worker when it boots to setup
|
@@ -304,7 +327,8 @@ module Puma
|
|
304
327
|
# This can be called multiple times to add hooks.
|
305
328
|
#
|
306
329
|
def on_worker_boot(&block)
|
307
|
-
|
330
|
+
@options[:before_worker_boot] ||= []
|
331
|
+
@options[:before_worker_boot] << block
|
308
332
|
end
|
309
333
|
|
310
334
|
# *Cluster mode only* Code to run immediately before a worker shuts
|
@@ -315,7 +339,8 @@ module Puma
|
|
315
339
|
# This can be called multiple times to add hooks.
|
316
340
|
#
|
317
341
|
def on_worker_shutdown(&block)
|
318
|
-
|
342
|
+
@options[:before_worker_shutdown] ||= []
|
343
|
+
@options[:before_worker_shutdown] << block
|
319
344
|
end
|
320
345
|
|
321
346
|
# *Cluster mode only* Code to run in the master when it is
|
@@ -324,7 +349,8 @@ module Puma
|
|
324
349
|
# This can be called multiple times to add hooks.
|
325
350
|
#
|
326
351
|
def on_worker_fork(&block)
|
327
|
-
|
352
|
+
@options[:before_worker_fork] ||= []
|
353
|
+
@options[:before_worker_fork] << block
|
328
354
|
end
|
329
355
|
|
330
356
|
# *Cluster mode only* Code to run in the master after it starts
|
@@ -333,7 +359,8 @@ module Puma
|
|
333
359
|
# This can be called multiple times to add hooks.
|
334
360
|
#
|
335
361
|
def after_worker_fork(&block)
|
336
|
-
|
362
|
+
@options[:after_worker_fork] ||= []
|
363
|
+
@options[:after_worker_fork] = block
|
337
364
|
end
|
338
365
|
|
339
366
|
alias_method :after_worker_boot, :after_worker_fork
|
@@ -397,17 +424,17 @@ module Puma
|
|
397
424
|
# that have not checked in within the given +timeout+.
|
398
425
|
# This mitigates hung processes. Default value is 60 seconds.
|
399
426
|
def worker_timeout(timeout)
|
400
|
-
@options[:worker_timeout] = timeout
|
427
|
+
@options[:worker_timeout] = Integer(timeout)
|
401
428
|
end
|
402
429
|
|
403
430
|
# *Cluster mode only* Set the timeout for workers to boot
|
404
431
|
def worker_boot_timeout(timeout)
|
405
|
-
@options[:worker_boot_timeout] = timeout
|
432
|
+
@options[:worker_boot_timeout] = Integer(timeout)
|
406
433
|
end
|
407
434
|
|
408
435
|
# *Cluster mode only* Set the timeout for worker shutdown
|
409
436
|
def worker_shutdown_timeout(timeout)
|
410
|
-
@options[:worker_shutdown_timeout] = timeout
|
437
|
+
@options[:worker_shutdown_timeout] = Integer(timeout)
|
411
438
|
end
|
412
439
|
|
413
440
|
# When set to true (the default), workers accept all requests
|
@@ -475,10 +502,5 @@ module Puma
|
|
475
502
|
end
|
476
503
|
end
|
477
504
|
|
478
|
-
private
|
479
|
-
|
480
|
-
def _ary(key)
|
481
|
-
(@options.cur[key] ||= [])
|
482
|
-
end
|
483
505
|
end
|
484
506
|
end
|