puma 2.16.0-java → 3.0.0-java
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 +4 -4
- data/Gemfile +1 -1
- data/History.txt +50 -0
- data/Manifest.txt +5 -1
- data/README.md +25 -13
- data/ext/puma_http11/http11_parser.java.rl +5 -5
- data/ext/puma_http11/io_buffer.c +1 -1
- data/ext/puma_http11/mini_ssl.c +7 -1
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +39 -39
- data/lib/puma.rb +1 -0
- data/lib/puma/app/status.rb +1 -1
- data/lib/puma/binder.rb +14 -3
- data/lib/puma/cli.rb +128 -493
- data/lib/puma/client.rb +4 -0
- data/lib/puma/cluster.rb +68 -52
- data/lib/puma/configuration.rb +192 -61
- data/lib/puma/const.rb +2 -2
- data/lib/puma/control_cli.rb +58 -73
- data/lib/puma/convenient.rb +23 -0
- data/lib/puma/daemon_ext.rb +6 -0
- data/lib/puma/detect.rb +8 -1
- data/lib/puma/dsl.rb +113 -28
- data/lib/puma/events.rb +5 -0
- data/lib/puma/launcher.rb +397 -0
- data/lib/puma/null_io.rb +15 -0
- data/lib/puma/plugin.rb +91 -0
- data/lib/puma/plugin/tmp_restart.rb +23 -0
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/runner.rb +19 -14
- data/lib/puma/server.rb +82 -48
- data/lib/puma/single.rb +9 -4
- data/lib/puma/state_file.rb +29 -0
- data/lib/puma/thread_pool.rb +8 -3
- data/lib/rack/handler/puma.rb +34 -27
- metadata +7 -3
- data/COPYING +0 -55
data/lib/puma/const.rb
CHANGED
@@ -99,8 +99,8 @@ module Puma
|
|
99
99
|
# too taxing on performance.
|
100
100
|
module Const
|
101
101
|
|
102
|
-
PUMA_VERSION = VERSION = "
|
103
|
-
CODE_NAME = "
|
102
|
+
PUMA_VERSION = VERSION = "3.0.0".freeze
|
103
|
+
CODE_NAME = "Plethora of Penguin Pinatas".freeze
|
104
104
|
|
105
105
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
106
106
|
|
data/lib/puma/control_cli.rb
CHANGED
@@ -1,20 +1,25 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
require 'puma/const'
|
3
3
|
require 'puma/configuration'
|
4
|
-
require 'yaml'
|
5
4
|
require 'uri'
|
6
5
|
require 'socket'
|
6
|
+
|
7
7
|
module Puma
|
8
8
|
class ControlCLI
|
9
9
|
|
10
10
|
COMMANDS = %w{halt restart phased-restart start stats status stop reload-worker-directory}
|
11
11
|
|
12
|
-
def is_windows?
|
13
|
-
RUBY_PLATFORM =~ /(win|w)32$/ ? true : false
|
14
|
-
end
|
15
|
-
|
16
12
|
def initialize(argv, stdout=STDOUT, stderr=STDERR)
|
17
|
-
@
|
13
|
+
@state = nil
|
14
|
+
@quiet = false
|
15
|
+
@pidfile = nil
|
16
|
+
@pid = nil
|
17
|
+
@control_url = nil
|
18
|
+
@control_auth_token = nil
|
19
|
+
@config_file = nil
|
20
|
+
@command = nil
|
21
|
+
|
22
|
+
@argv = argv.dup
|
18
23
|
@stdout = stdout
|
19
24
|
@stderr = stderr
|
20
25
|
@cli_options = {}
|
@@ -23,31 +28,31 @@ module Puma
|
|
23
28
|
o.banner = "Usage: pumactl (-p PID | -P pidfile | -S status_file | -C url -T token | -F config.rb) (#{COMMANDS.join("|")})"
|
24
29
|
|
25
30
|
o.on "-S", "--state PATH", "Where the state file to use is" do |arg|
|
26
|
-
@
|
31
|
+
@state = arg
|
27
32
|
end
|
28
33
|
|
29
34
|
o.on "-Q", "--quiet", "Not display messages" do |arg|
|
30
|
-
@
|
35
|
+
@quiet = true
|
31
36
|
end
|
32
37
|
|
33
38
|
o.on "-P", "--pidfile PATH", "Pid file" do |arg|
|
34
|
-
@
|
39
|
+
@pidfile = arg
|
35
40
|
end
|
36
41
|
|
37
42
|
o.on "-p", "--pid PID", "Pid" do |arg|
|
38
|
-
@
|
43
|
+
@pid = arg.to_i
|
39
44
|
end
|
40
45
|
|
41
46
|
o.on "-C", "--control-url URL", "The bind url to use for the control server" do |arg|
|
42
|
-
@
|
47
|
+
@control_url = arg
|
43
48
|
end
|
44
49
|
|
45
50
|
o.on "-T", "--control-token TOKEN", "The token to use as authentication for the control server" do |arg|
|
46
|
-
@
|
51
|
+
@control_auth_token = arg
|
47
52
|
end
|
48
53
|
|
49
54
|
o.on "-F", "--config-file PATH", "Puma config script" do |arg|
|
50
|
-
@
|
55
|
+
@config_file = arg
|
51
56
|
end
|
52
57
|
|
53
58
|
o.on_tail("-H", "--help", "Show this message") do
|
@@ -63,32 +68,29 @@ module Puma
|
|
63
68
|
|
64
69
|
opts.order!(argv) { |a| opts.terminate a }
|
65
70
|
|
66
|
-
command = argv.shift
|
67
|
-
@cli_options[:command] = command if command
|
71
|
+
@command = argv.shift
|
68
72
|
|
69
|
-
@
|
70
|
-
|
71
|
-
|
72
|
-
if @cli_options[:config_file].nil? and File.exist?('config/puma.rb')
|
73
|
-
@cli_options[:config_file] = 'config/puma.rb'
|
73
|
+
unless @config_file == '-'
|
74
|
+
if @config_file.nil? and File.exist?('config/puma.rb')
|
75
|
+
@config_file = 'config/puma.rb'
|
74
76
|
end
|
75
77
|
|
76
|
-
if @
|
77
|
-
config = Puma::Configuration.
|
78
|
-
config.
|
79
|
-
@
|
78
|
+
if @config_file
|
79
|
+
config = Puma::Configuration.from_file @config_file
|
80
|
+
@state ||= config.options[:state]
|
81
|
+
@control_url ||= config.options[:control_url]
|
82
|
+
@control_auth_token ||= config.options[:control_auth_token]
|
83
|
+
@pidfile ||= config.options[:pidfile]
|
80
84
|
end
|
81
85
|
end
|
82
86
|
|
83
|
-
@options ||= @cli_options
|
84
|
-
|
85
87
|
# check present of command
|
86
|
-
unless @
|
88
|
+
unless @command
|
87
89
|
raise "Available commands: #{COMMANDS.join(", ")}"
|
88
90
|
end
|
89
91
|
|
90
|
-
unless COMMANDS.include? @
|
91
|
-
raise "Invalid command: #{@
|
92
|
+
unless COMMANDS.include? @command
|
93
|
+
raise "Invalid command: #{@command}"
|
92
94
|
end
|
93
95
|
|
94
96
|
rescue => e
|
@@ -97,45 +99,29 @@ module Puma
|
|
97
99
|
end
|
98
100
|
|
99
101
|
def message(msg)
|
100
|
-
@stdout.puts msg unless @
|
102
|
+
@stdout.puts msg unless @quiet
|
101
103
|
end
|
102
104
|
|
103
105
|
def prepare_configuration
|
104
|
-
if @
|
105
|
-
unless File.exist? @
|
106
|
-
raise "
|
106
|
+
if @state
|
107
|
+
unless File.exist? @state
|
108
|
+
raise "State file not found: #{@state}"
|
107
109
|
end
|
108
110
|
|
109
|
-
|
110
|
-
|
111
|
-
if status.kind_of?(Hash) && status.has_key?("config")
|
112
|
-
|
113
|
-
conf = status["config"]
|
114
|
-
|
115
|
-
# get control_url
|
116
|
-
if url = conf.options[:control_url]
|
117
|
-
@options[:control_url] = url
|
118
|
-
end
|
119
|
-
|
120
|
-
# get control_auth_token
|
121
|
-
if token = conf.options[:control_auth_token]
|
122
|
-
@options[:control_auth_token] = token
|
123
|
-
end
|
124
|
-
|
125
|
-
# get pid
|
126
|
-
@options[:pid] = status["pid"].to_i
|
127
|
-
else
|
128
|
-
raise "Invalid status file: #{@options[:state]}"
|
129
|
-
end
|
111
|
+
sf = StateFile.new
|
112
|
+
sf.load @state
|
130
113
|
|
131
|
-
|
114
|
+
@control_url = sf.control_url
|
115
|
+
@control_auth_token = sf.control_auth_token
|
116
|
+
@pid = sf.pid
|
117
|
+
elsif @pidfile
|
132
118
|
# get pid from pid_file
|
133
|
-
@
|
119
|
+
@pid = File.open(@pidfile).gets.to_i
|
134
120
|
end
|
135
121
|
end
|
136
122
|
|
137
123
|
def send_request
|
138
|
-
uri = URI.parse @
|
124
|
+
uri = URI.parse @control_url
|
139
125
|
|
140
126
|
# create server object by scheme
|
141
127
|
@server = case uri.scheme
|
@@ -147,13 +133,13 @@ module Puma
|
|
147
133
|
raise "Invalid scheme: #{uri.scheme}"
|
148
134
|
end
|
149
135
|
|
150
|
-
if @
|
136
|
+
if @command == "status"
|
151
137
|
message "Puma is started"
|
152
138
|
else
|
153
|
-
url = "/#{@
|
139
|
+
url = "/#{@command}"
|
154
140
|
|
155
|
-
if @
|
156
|
-
url = url + "?token=#{@
|
141
|
+
if @control_auth_token
|
142
|
+
url = url + "?token=#{@control_auth_token}"
|
157
143
|
end
|
158
144
|
|
159
145
|
@server << "GET #{url} HTTP/1.0\r\n\r\n"
|
@@ -178,30 +164,29 @@ module Puma
|
|
178
164
|
raise "Bad response from server: #{@code}"
|
179
165
|
end
|
180
166
|
|
181
|
-
message "Command #{@
|
182
|
-
message response.last if @
|
167
|
+
message "Command #{@command} sent success"
|
168
|
+
message response.last if @command == "stats"
|
183
169
|
end
|
184
170
|
|
185
171
|
@server.close
|
186
172
|
end
|
187
173
|
|
188
174
|
def send_signal
|
189
|
-
unless
|
175
|
+
unless @pid
|
190
176
|
raise "Neither pid nor control url available"
|
191
177
|
end
|
192
178
|
|
193
179
|
begin
|
194
180
|
Process.getpgid pid
|
195
181
|
rescue SystemCallError
|
196
|
-
if @
|
197
|
-
@options.delete(:command)
|
182
|
+
if @command == "restart"
|
198
183
|
start
|
199
184
|
else
|
200
185
|
raise "No pid '#{pid}' found"
|
201
186
|
end
|
202
187
|
end
|
203
188
|
|
204
|
-
case @
|
189
|
+
case @command
|
205
190
|
when "restart"
|
206
191
|
Process.kill "SIGUSR2", pid
|
207
192
|
|
@@ -227,18 +212,18 @@ module Puma
|
|
227
212
|
return
|
228
213
|
end
|
229
214
|
|
230
|
-
message "Command #{@
|
215
|
+
message "Command #{@command} sent success"
|
231
216
|
end
|
232
217
|
|
233
218
|
def run
|
234
|
-
start if @
|
219
|
+
start if @command == "start"
|
235
220
|
|
236
221
|
prepare_configuration
|
237
222
|
|
238
|
-
if
|
223
|
+
if Puma.windows?
|
239
224
|
send_request
|
240
225
|
else
|
241
|
-
@
|
226
|
+
@control_url ? send_request : send_signal
|
242
227
|
end
|
243
228
|
|
244
229
|
rescue => e
|
@@ -252,11 +237,11 @@ module Puma
|
|
252
237
|
|
253
238
|
run_args = @argv
|
254
239
|
|
255
|
-
if path = @
|
240
|
+
if path = @state
|
256
241
|
run_args = ["-S", path] + run_args
|
257
242
|
end
|
258
243
|
|
259
|
-
if path = @
|
244
|
+
if path = @config_file
|
260
245
|
run_args = ["-C", path] + run_args
|
261
246
|
end
|
262
247
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'puma/launcher'
|
2
|
+
require 'puma/configuration'
|
3
|
+
|
4
|
+
module Puma
|
5
|
+
def self.run(opts={})
|
6
|
+
cfg = Puma::Configuration.new do |c|
|
7
|
+
if port = opts[:port]
|
8
|
+
c.port port
|
9
|
+
end
|
10
|
+
|
11
|
+
c.quiet
|
12
|
+
|
13
|
+
yield c
|
14
|
+
end
|
15
|
+
|
16
|
+
cfg.clamp
|
17
|
+
|
18
|
+
events = Puma::Events.null
|
19
|
+
|
20
|
+
launcher = Puma::Launcher.new cfg, :events => events
|
21
|
+
launcher.run
|
22
|
+
end
|
23
|
+
end
|
data/lib/puma/daemon_ext.rb
CHANGED
@@ -3,6 +3,12 @@ module Process
|
|
3
3
|
# This overrides the default version because it is broken if it
|
4
4
|
# exists.
|
5
5
|
|
6
|
+
if respond_to? :daemon
|
7
|
+
class << self
|
8
|
+
remove_method :daemon
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
6
12
|
def self.daemon(nochdir=false, noclose=false)
|
7
13
|
exit if fork # Parent exits, child continues.
|
8
14
|
|
data/lib/puma/detect.rb
CHANGED
data/lib/puma/dsl.rb
CHANGED
@@ -4,20 +4,57 @@ module Puma
|
|
4
4
|
class DSL
|
5
5
|
include ConfigDefault
|
6
6
|
|
7
|
-
def self.load(options, path)
|
8
|
-
new(options)
|
9
|
-
|
10
|
-
end
|
7
|
+
def self.load(options, cfg, path)
|
8
|
+
d = new(options, cfg)
|
9
|
+
d._load_from(path)
|
11
10
|
|
12
11
|
options
|
12
|
+
ensure
|
13
|
+
d._offer_plugins
|
13
14
|
end
|
14
15
|
|
15
|
-
def initialize(options)
|
16
|
+
def initialize(options, config)
|
17
|
+
@config = config
|
16
18
|
@options = options
|
19
|
+
|
20
|
+
@plugins = []
|
17
21
|
end
|
18
22
|
|
19
23
|
def _load_from(path)
|
20
24
|
instance_eval(File.read(path), path, 1) if path
|
25
|
+
ensure
|
26
|
+
_offer_plugins
|
27
|
+
end
|
28
|
+
|
29
|
+
def _offer_plugins
|
30
|
+
@plugins.each do |o|
|
31
|
+
if o.respond_to? :config
|
32
|
+
@options.shift
|
33
|
+
o.config self
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
@plugins.clear
|
38
|
+
end
|
39
|
+
|
40
|
+
def _run(&blk)
|
41
|
+
blk.call self
|
42
|
+
ensure
|
43
|
+
_offer_plugins
|
44
|
+
end
|
45
|
+
|
46
|
+
def inject(&blk)
|
47
|
+
instance_eval(&blk)
|
48
|
+
end
|
49
|
+
|
50
|
+
def get(key,default=nil)
|
51
|
+
@options[key.to_sym] || default
|
52
|
+
end
|
53
|
+
|
54
|
+
# Load the named plugin for use by this configuration
|
55
|
+
#
|
56
|
+
def plugin(name)
|
57
|
+
@plugins << @config.load_plugin(name)
|
21
58
|
end
|
22
59
|
|
23
60
|
# Use +obj+ or +block+ as the Rack app. This allows a config file to
|
@@ -34,29 +71,43 @@ module Puma
|
|
34
71
|
# Start the Puma control rack app on +url+. This app can be communicated
|
35
72
|
# with to control the main server.
|
36
73
|
#
|
37
|
-
def activate_control_app(url="auto", opts=
|
38
|
-
|
74
|
+
def activate_control_app(url="auto", opts={})
|
75
|
+
if url == "auto"
|
76
|
+
path = Configuration.temp_path
|
77
|
+
@options[:control_url] = "unix://#{path}"
|
78
|
+
@options[:control_url_temp] = path
|
79
|
+
else
|
80
|
+
@options[:control_url] = url
|
81
|
+
end
|
39
82
|
|
40
|
-
if opts
|
83
|
+
if opts[:no_token]
|
84
|
+
auth_token = :none
|
85
|
+
else
|
41
86
|
auth_token = opts[:auth_token]
|
42
|
-
|
43
|
-
|
44
|
-
@options[:control_auth_token] = :none if opts[:no_token]
|
45
|
-
@options[:control_url_umask] = opts[:umask] if opts[:umask]
|
87
|
+
auth_token ||= Configuration.random_token
|
46
88
|
end
|
89
|
+
|
90
|
+
@options[:control_auth_token] = auth_token
|
91
|
+
@options[:control_url_umask] = opts[:umask] if opts[:umask]
|
92
|
+
end
|
93
|
+
|
94
|
+
# Load additional configuration from a file
|
95
|
+
def load(file)
|
96
|
+
_ary(:config_files) << file
|
47
97
|
end
|
48
98
|
|
49
99
|
# Bind the server to +url+. tcp:// and unix:// are the only accepted
|
50
100
|
# protocols.
|
51
101
|
#
|
52
102
|
def bind(url)
|
53
|
-
|
103
|
+
_ary(:binds) << url
|
54
104
|
end
|
55
105
|
|
56
106
|
# Define the TCP port to bind to. Use +bind+ for more advanced options.
|
57
107
|
#
|
58
|
-
def port(port)
|
59
|
-
|
108
|
+
def port(port, host=nil)
|
109
|
+
host ||= Configuration::DefaultTCPHost
|
110
|
+
bind "tcp://#{host}:#{port}"
|
60
111
|
end
|
61
112
|
|
62
113
|
# Work around leaky apps that leave garbage in Thread locals
|
@@ -91,7 +142,7 @@ module Puma
|
|
91
142
|
# This can be called multiple times to add code each time.
|
92
143
|
#
|
93
144
|
def on_restart(&block)
|
94
|
-
|
145
|
+
_ary(:on_restart) << block
|
95
146
|
end
|
96
147
|
|
97
148
|
# Command to use to restart puma. This should be just how to
|
@@ -99,18 +150,30 @@ module Puma
|
|
99
150
|
# to puma, as those are the same as the original process.
|
100
151
|
#
|
101
152
|
def restart_command(cmd)
|
102
|
-
@options[:restart_cmd] = cmd
|
153
|
+
@options[:restart_cmd] = cmd.to_s
|
103
154
|
end
|
104
155
|
|
105
156
|
# Store the pid of the server in the file at +path+.
|
106
157
|
def pidfile(path)
|
107
|
-
@options[:pidfile] = path
|
158
|
+
@options[:pidfile] = path.to_s
|
108
159
|
end
|
109
160
|
|
110
161
|
# Disable request logging.
|
111
162
|
#
|
112
|
-
def quiet
|
113
|
-
@options[:
|
163
|
+
def quiet(which=true)
|
164
|
+
@options[:log_requests] = !which
|
165
|
+
end
|
166
|
+
|
167
|
+
# Enable request logging
|
168
|
+
#
|
169
|
+
def log_requests(which=true)
|
170
|
+
@options[:log_requests] = which
|
171
|
+
end
|
172
|
+
|
173
|
+
# Show debugging info
|
174
|
+
#
|
175
|
+
def debug
|
176
|
+
@options[:debug] = true
|
114
177
|
end
|
115
178
|
|
116
179
|
# Load +path+ as a rackup file.
|
@@ -119,6 +182,12 @@ module Puma
|
|
119
182
|
@options[:rackup] = path.to_s
|
120
183
|
end
|
121
184
|
|
185
|
+
# Run Puma in TCP mode
|
186
|
+
#
|
187
|
+
def tcp_mode!
|
188
|
+
@options[:mode] = :tcp
|
189
|
+
end
|
190
|
+
|
122
191
|
# Redirect STDOUT and STDERR to files specified.
|
123
192
|
def stdout_redirect(stdout=nil, stderr=nil, append=false)
|
124
193
|
@options[:redirect_stdout] = stdout
|
@@ -136,6 +205,10 @@ module Puma
|
|
136
205
|
raise "The minimum (#{min}) number of threads must be less than or equal to the max (#{max})"
|
137
206
|
end
|
138
207
|
|
208
|
+
if max < 1
|
209
|
+
raise "The maximum number of threads (#{max}) must be greater than 0"
|
210
|
+
end
|
211
|
+
|
139
212
|
@options[:min_threads] = min
|
140
213
|
@options[:max_threads] = max
|
141
214
|
end
|
@@ -143,9 +216,9 @@ module Puma
|
|
143
216
|
def ssl_bind(host, port, opts)
|
144
217
|
if defined?(JRUBY_VERSION)
|
145
218
|
keystore_additions = "keystore=#{opts[:keystore]}&keystore-pass=#{opts[:keystore_pass]}"
|
146
|
-
|
219
|
+
bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}&#{keystore_additions}"
|
147
220
|
else
|
148
|
-
|
221
|
+
bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}"
|
149
222
|
end
|
150
223
|
end
|
151
224
|
|
@@ -172,7 +245,7 @@ module Puma
|
|
172
245
|
# This can be called multiple times to add hooks.
|
173
246
|
#
|
174
247
|
def before_fork(&block)
|
175
|
-
|
248
|
+
_ary(:before_fork) << block
|
176
249
|
end
|
177
250
|
|
178
251
|
# *Cluster mode only* Code to run immediately before a worker shuts
|
@@ -183,7 +256,7 @@ module Puma
|
|
183
256
|
# This can be called multiple times to add hooks.
|
184
257
|
#
|
185
258
|
def on_worker_shutdown(&block)
|
186
|
-
|
259
|
+
_ary(:before_worker_shutdown) << block
|
187
260
|
end
|
188
261
|
|
189
262
|
# *Cluster mode only* Code to run when a worker boots to setup
|
@@ -192,7 +265,7 @@ module Puma
|
|
192
265
|
# This can be called multiple times to add hooks.
|
193
266
|
#
|
194
267
|
def on_worker_boot(&block)
|
195
|
-
|
268
|
+
_ary(:before_worker_boot) << block
|
196
269
|
end
|
197
270
|
|
198
271
|
# *Cluster mode only* Code to run when a master process is
|
@@ -201,7 +274,7 @@ module Puma
|
|
201
274
|
# This can be called multiple times to add hooks.
|
202
275
|
#
|
203
276
|
def on_worker_fork(&block)
|
204
|
-
|
277
|
+
_ary(:before_worker_fork) << block
|
205
278
|
end
|
206
279
|
|
207
280
|
# *Cluster mode only* Code to run when a worker boots to setup
|
@@ -210,12 +283,18 @@ module Puma
|
|
210
283
|
# This can be called multiple times to add hooks.
|
211
284
|
#
|
212
285
|
def after_worker_boot(&block)
|
213
|
-
|
286
|
+
_ary(:after_worker_fork) << block
|
214
287
|
end
|
215
288
|
|
216
289
|
# The directory to operate out of.
|
217
290
|
def directory(dir)
|
218
291
|
@options[:directory] = dir.to_s
|
292
|
+
|
293
|
+
worker_directory dir
|
294
|
+
end
|
295
|
+
|
296
|
+
# Set the directory for workers to start in
|
297
|
+
def worker_directory(dir)
|
219
298
|
@options[:worker_directory] = dir.to_s
|
220
299
|
end
|
221
300
|
|
@@ -259,7 +338,7 @@ module Puma
|
|
259
338
|
|
260
339
|
# Additional text to display in process listing
|
261
340
|
def tag(string)
|
262
|
-
@options[:tag] = string
|
341
|
+
@options[:tag] = string.to_s
|
263
342
|
end
|
264
343
|
|
265
344
|
# *Cluster mode only* Set the timeout for workers in seconds
|
@@ -344,5 +423,11 @@ module Puma
|
|
344
423
|
raise "Invalid value for set_remote_address - #{val}"
|
345
424
|
end
|
346
425
|
end
|
426
|
+
|
427
|
+
private
|
428
|
+
|
429
|
+
def _ary(key)
|
430
|
+
(@options.cur[key] ||= [])
|
431
|
+
end
|
347
432
|
end
|
348
433
|
end
|