puma 3.12.0 → 4.3.8
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/History.md +164 -0
- data/README.md +76 -48
- data/docs/architecture.md +1 -0
- data/docs/deployment.md +24 -4
- data/docs/plugins.md +20 -10
- data/docs/restart.md +4 -2
- data/docs/systemd.md +27 -9
- data/docs/tcp_mode.md +96 -0
- data/ext/puma_http11/PumaHttp11Service.java +2 -0
- data/ext/puma_http11/extconf.rb +13 -0
- data/ext/puma_http11/http11_parser.c +40 -63
- data/ext/puma_http11/http11_parser.java.rl +21 -37
- data/ext/puma_http11/http11_parser.rl +3 -1
- data/ext/puma_http11/http11_parser_common.rl +3 -3
- data/ext/puma_http11/mini_ssl.c +86 -4
- data/ext/puma_http11/org/jruby/puma/Http11.java +106 -114
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +91 -106
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +72 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +15 -4
- data/ext/puma_http11/puma_http11.c +3 -0
- data/lib/puma.rb +8 -0
- data/lib/puma/accept_nonblock.rb +7 -1
- data/lib/puma/app/status.rb +37 -29
- data/lib/puma/binder.rb +47 -68
- data/lib/puma/cli.rb +6 -0
- data/lib/puma/client.rb +244 -199
- data/lib/puma/cluster.rb +55 -30
- data/lib/puma/commonlogger.rb +2 -0
- data/lib/puma/configuration.rb +6 -3
- data/lib/puma/const.rb +32 -18
- data/lib/puma/control_cli.rb +41 -14
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +311 -77
- data/lib/puma/events.rb +6 -1
- data/lib/puma/io_buffer.rb +3 -6
- data/lib/puma/jruby_restart.rb +2 -0
- data/lib/puma/launcher.rb +99 -55
- data/lib/puma/minissl.rb +37 -17
- data/lib/puma/minissl/context_builder.rb +76 -0
- data/lib/puma/null_io.rb +2 -0
- data/lib/puma/plugin.rb +7 -2
- data/lib/puma/plugin/tmp_restart.rb +2 -0
- data/lib/puma/rack/builder.rb +4 -1
- data/lib/puma/rack/urlmap.rb +2 -0
- data/lib/puma/rack_default.rb +2 -0
- data/lib/puma/reactor.rb +112 -57
- data/lib/puma/runner.rb +13 -3
- data/lib/puma/server.rb +119 -48
- data/lib/puma/single.rb +5 -3
- data/lib/puma/state_file.rb +2 -0
- data/lib/puma/tcp_logger.rb +2 -0
- data/lib/puma/thread_pool.rb +17 -33
- data/lib/puma/util.rb +2 -6
- data/lib/rack/handler/puma.rb +6 -3
- data/tools/docker/Dockerfile +16 -0
- data/tools/jungle/init.d/puma +6 -6
- data/tools/trickletest.rb +0 -1
- metadata +26 -14
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/convenient.rb +0 -23
- data/lib/puma/daemon_ext.rb +0 -31
- data/lib/puma/delegation.rb +0 -11
- data/lib/puma/java_io_buffer.rb +0 -45
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
data/lib/puma/cluster.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'puma/runner'
|
2
4
|
require 'puma/util'
|
3
5
|
require 'puma/plugin'
|
@@ -17,8 +19,6 @@ module Puma
|
|
17
19
|
# via the `spawn_workers` method call. Each worker will have it's own
|
18
20
|
# instance of a `Puma::Server`.
|
19
21
|
class Cluster < Runner
|
20
|
-
WORKER_CHECK_INTERVAL = 5
|
21
|
-
|
22
22
|
def initialize(cli, events)
|
23
23
|
super cli, events
|
24
24
|
|
@@ -35,7 +35,11 @@ module Puma
|
|
35
35
|
@workers.each { |x| x.term }
|
36
36
|
|
37
37
|
begin
|
38
|
-
|
38
|
+
loop do
|
39
|
+
wait_workers
|
40
|
+
break if @workers.empty?
|
41
|
+
sleep 0.2
|
42
|
+
end
|
39
43
|
rescue Interrupt
|
40
44
|
log "! Cancelled waiting for workers"
|
41
45
|
end
|
@@ -67,12 +71,13 @@ module Puma
|
|
67
71
|
@signal = "TERM"
|
68
72
|
@options = options
|
69
73
|
@first_term_sent = nil
|
74
|
+
@started_at = Time.now
|
70
75
|
@last_checkin = Time.now
|
71
76
|
@last_status = '{}'
|
72
|
-
@
|
77
|
+
@term = false
|
73
78
|
end
|
74
79
|
|
75
|
-
attr_reader :index, :pid, :phase, :signal, :last_checkin, :last_status
|
80
|
+
attr_reader :index, :pid, :phase, :signal, :last_checkin, :last_status, :started_at
|
76
81
|
|
77
82
|
def booted?
|
78
83
|
@stage == :booted
|
@@ -83,12 +88,8 @@ module Puma
|
|
83
88
|
@stage = :booted
|
84
89
|
end
|
85
90
|
|
86
|
-
def
|
87
|
-
@
|
88
|
-
end
|
89
|
-
|
90
|
-
def dead!
|
91
|
-
@dead = true
|
91
|
+
def term?
|
92
|
+
@term
|
92
93
|
end
|
93
94
|
|
94
95
|
def ping!(status)
|
@@ -105,9 +106,9 @@ module Puma
|
|
105
106
|
if @first_term_sent && (Time.now - @first_term_sent) > @options[:worker_shutdown_timeout]
|
106
107
|
@signal = "KILL"
|
107
108
|
else
|
109
|
+
@term ||= true
|
108
110
|
@first_term_sent ||= Time.now
|
109
111
|
end
|
110
|
-
|
111
112
|
Process.kill @signal, @pid
|
112
113
|
rescue Errno::ESRCH
|
113
114
|
end
|
@@ -181,7 +182,7 @@ module Puma
|
|
181
182
|
def check_workers(force=false)
|
182
183
|
return if !force && @next_check && @next_check >= Time.now
|
183
184
|
|
184
|
-
@next_check = Time.now + WORKER_CHECK_INTERVAL
|
185
|
+
@next_check = Time.now + Const::WORKER_CHECK_INTERVAL
|
185
186
|
|
186
187
|
any = false
|
187
188
|
|
@@ -198,15 +199,7 @@ module Puma
|
|
198
199
|
# during this loop by giving the kernel time to kill them.
|
199
200
|
sleep 1 if any
|
200
201
|
|
201
|
-
|
202
|
-
pid = Process.waitpid(-1, Process::WNOHANG)
|
203
|
-
break unless pid
|
204
|
-
|
205
|
-
@workers.delete_if { |w| w.pid == pid }
|
206
|
-
end
|
207
|
-
|
208
|
-
@workers.delete_if(&:dead?)
|
209
|
-
|
202
|
+
wait_workers
|
210
203
|
cull_workers
|
211
204
|
spawn_workers
|
212
205
|
|
@@ -223,8 +216,10 @@ module Puma
|
|
223
216
|
log "- Stopping #{w.pid} for phased upgrade..."
|
224
217
|
end
|
225
218
|
|
226
|
-
w.term
|
227
|
-
|
219
|
+
unless w.term?
|
220
|
+
w.term
|
221
|
+
log "- #{w.signal} sent to #{w.pid}..."
|
222
|
+
end
|
228
223
|
end
|
229
224
|
end
|
230
225
|
end
|
@@ -251,6 +246,7 @@ module Puma
|
|
251
246
|
@suicide_pipe.close
|
252
247
|
|
253
248
|
Thread.new do
|
249
|
+
Puma.set_thread_name "worker check pipe"
|
254
250
|
IO.select [@check_pipe]
|
255
251
|
log "! Detected parent died, dying"
|
256
252
|
exit! 1
|
@@ -273,6 +269,7 @@ module Puma
|
|
273
269
|
server = start_server
|
274
270
|
|
275
271
|
Signal.trap "SIGTERM" do
|
272
|
+
@worker_write << "e#{Process.pid}\n" rescue nil
|
276
273
|
server.stop
|
277
274
|
end
|
278
275
|
|
@@ -285,10 +282,11 @@ module Puma
|
|
285
282
|
end
|
286
283
|
|
287
284
|
Thread.new(@worker_write) do |io|
|
285
|
+
Puma.set_thread_name "stat payload"
|
288
286
|
base_payload = "p#{Process.pid}"
|
289
287
|
|
290
288
|
while true
|
291
|
-
sleep WORKER_CHECK_INTERVAL
|
289
|
+
sleep Const::WORKER_CHECK_INTERVAL
|
292
290
|
begin
|
293
291
|
b = server.backlog || 0
|
294
292
|
r = server.running || 0
|
@@ -350,11 +348,13 @@ module Puma
|
|
350
348
|
Dir.chdir dir
|
351
349
|
end
|
352
350
|
|
351
|
+
# Inside of a child process, this will return all zeroes, as @workers is only populated in
|
352
|
+
# the master process.
|
353
353
|
def stats
|
354
354
|
old_worker_count = @workers.count { |w| w.phase != @phase }
|
355
355
|
booted_worker_count = @workers.count { |w| w.booted? }
|
356
|
-
worker_status = '[' + @workers.map { |w| %Q!{ "pid": #{w.pid}, "index": #{w.index}, "phase": #{w.phase}, "booted": #{w.booted?}, "last_checkin": "#{w.last_checkin.utc.iso8601}", "last_status": #{w.last_status} }!}.join(",") + ']'
|
357
|
-
%Q!{ "workers": #{@workers.size}, "phase": #{@phase}, "booted_workers": #{booted_worker_count}, "old_workers": #{old_worker_count}, "worker_status": #{worker_status} }!
|
356
|
+
worker_status = '[' + @workers.map { |w| %Q!{ "started_at": "#{w.started_at.utc.iso8601}", "pid": #{w.pid}, "index": #{w.index}, "phase": #{w.phase}, "booted": #{w.booted?}, "last_checkin": "#{w.last_checkin.utc.iso8601}", "last_status": #{w.last_status} }!}.join(",") + ']'
|
357
|
+
%Q!{ "started_at": "#{@started_at.utc.iso8601}", "workers": #{@workers.size}, "phase": #{@phase}, "booted_workers": #{booted_worker_count}, "old_workers": #{old_worker_count}, "worker_status": #{worker_status} }!
|
358
358
|
end
|
359
359
|
|
360
360
|
def preload?
|
@@ -388,10 +388,13 @@ module Puma
|
|
388
388
|
log "Early termination of worker"
|
389
389
|
exit! 0
|
390
390
|
else
|
391
|
+
@launcher.close_binder_listeners
|
392
|
+
|
391
393
|
stop_workers
|
392
394
|
stop
|
393
395
|
|
394
|
-
raise
|
396
|
+
raise(SignalException, "SIGTERM") if @options[:raise_exception_on_sigterm]
|
397
|
+
exit 0 # Clean exit, workers were stopped
|
395
398
|
end
|
396
399
|
end
|
397
400
|
end
|
@@ -485,7 +488,7 @@ module Puma
|
|
485
488
|
|
486
489
|
force_check = false
|
487
490
|
|
488
|
-
res = IO.select([read], nil, nil, WORKER_CHECK_INTERVAL)
|
491
|
+
res = IO.select([read], nil, nil, Const::WORKER_CHECK_INTERVAL)
|
489
492
|
|
490
493
|
if res
|
491
494
|
req = read.read_nonblock(1)
|
@@ -501,8 +504,11 @@ module Puma
|
|
501
504
|
w.boot!
|
502
505
|
log "- Worker #{w.index} (pid: #{pid}) booted, phase: #{w.phase}"
|
503
506
|
force_check = true
|
507
|
+
when "e"
|
508
|
+
# external term, see worker method, Signal.trap "SIGTERM"
|
509
|
+
w.instance_variable_set :@term, true
|
504
510
|
when "t"
|
505
|
-
w.
|
511
|
+
w.term unless w.term?
|
506
512
|
force_check = true
|
507
513
|
when "p"
|
508
514
|
w.ping!(result.sub(/^\d+/,'').chomp)
|
@@ -525,5 +531,24 @@ module Puma
|
|
525
531
|
@wakeup.close
|
526
532
|
end
|
527
533
|
end
|
534
|
+
|
535
|
+
private
|
536
|
+
|
537
|
+
# loops thru @workers, removing workers that exited, and calling
|
538
|
+
# `#term` if needed
|
539
|
+
def wait_workers
|
540
|
+
@workers.reject! do |w|
|
541
|
+
begin
|
542
|
+
if Process.wait(w.pid, Process::WNOHANG)
|
543
|
+
true
|
544
|
+
else
|
545
|
+
w.term if w.term?
|
546
|
+
nil
|
547
|
+
end
|
548
|
+
rescue Errno::ECHILD
|
549
|
+
true # child is already terminated
|
550
|
+
end
|
551
|
+
end
|
552
|
+
end
|
528
553
|
end
|
529
554
|
end
|
data/lib/puma/commonlogger.rb
CHANGED
data/lib/puma/configuration.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'puma/rack/builder'
|
2
4
|
require 'puma/plugin'
|
3
5
|
require 'puma/const'
|
@@ -18,7 +20,7 @@ module Puma
|
|
18
20
|
# In this class any "user" specified options take precedence over any
|
19
21
|
# "file" specified options, take precedence over any "default" options.
|
20
22
|
#
|
21
|
-
# User input is
|
23
|
+
# User input is preferred over "defaults":
|
22
24
|
# user_options = { foo: "bar" }
|
23
25
|
# default_options = { foo: "zoo" }
|
24
26
|
# options = UserFileDefaultOptions.new(user_options, default_options)
|
@@ -30,7 +32,7 @@ module Puma
|
|
30
32
|
# puts options.all_of(:foo)
|
31
33
|
# # => ["bar", "zoo"]
|
32
34
|
#
|
33
|
-
# A "file" option can be set. This config will be
|
35
|
+
# A "file" option can be set. This config will be preferred over "default" options
|
34
36
|
# but will defer to any available "user" specified options.
|
35
37
|
#
|
36
38
|
# user_options = { foo: "bar" }
|
@@ -184,7 +186,8 @@ module Puma
|
|
184
186
|
:rackup => DefaultRackup,
|
185
187
|
:logger => STDOUT,
|
186
188
|
:persistent_timeout => Const::PERSISTENT_TIMEOUT,
|
187
|
-
:first_data_timeout => Const::FIRST_DATA_TIMEOUT
|
189
|
+
:first_data_timeout => Const::FIRST_DATA_TIMEOUT,
|
190
|
+
:raise_exception_on_sigterm => true
|
188
191
|
}
|
189
192
|
end
|
190
193
|
|
data/lib/puma/const.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
module Puma
|
3
5
|
class UnsupportedOption < RuntimeError
|
4
6
|
end
|
@@ -98,8 +100,8 @@ module Puma
|
|
98
100
|
# too taxing on performance.
|
99
101
|
module Const
|
100
102
|
|
101
|
-
PUMA_VERSION = VERSION = "3.
|
102
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "4.3.8".freeze
|
104
|
+
CODE_NAME = "Mysterious Traveller".freeze
|
103
105
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
104
106
|
|
105
107
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
@@ -116,31 +118,35 @@ module Puma
|
|
116
118
|
# sending data back
|
117
119
|
WRITE_TIMEOUT = 10
|
118
120
|
|
121
|
+
# How many requests to attempt inline before sending a client back to
|
122
|
+
# the reactor to be subject to normal ordering. The idea here is that
|
123
|
+
# we amortize the cost of going back to the reactor for a well behaved
|
124
|
+
# but very "greedy" client across 10 requests. This prevents a not
|
125
|
+
# well behaved client from monopolizing the thread forever.
|
126
|
+
MAX_FAST_INLINE = 10
|
127
|
+
|
119
128
|
# The original URI requested by the client.
|
120
129
|
REQUEST_URI= 'REQUEST_URI'.freeze
|
121
130
|
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
122
131
|
QUERY_STRING = 'QUERY_STRING'.freeze
|
132
|
+
CONTENT_LENGTH = "CONTENT_LENGTH".freeze
|
123
133
|
|
124
134
|
PATH_INFO = 'PATH_INFO'.freeze
|
125
135
|
|
126
136
|
PUMA_TMP_BASE = "puma".freeze
|
127
137
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
ERROR_500_RESPONSE = "HTTP/1.1 500 Internal Server Error\r\n\r\n".freeze
|
141
|
-
|
142
|
-
# A common header for indicating the server is too busy. Not used yet.
|
143
|
-
ERROR_503_RESPONSE = "HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY".freeze
|
138
|
+
ERROR_RESPONSE = {
|
139
|
+
# Indicate that we couldn't parse the request
|
140
|
+
400 => "HTTP/1.1 400 Bad Request\r\n\r\n".freeze,
|
141
|
+
# The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
|
142
|
+
404 => "HTTP/1.1 404 Not Found\r\nConnection: close\r\nServer: Puma #{PUMA_VERSION}\r\n\r\nNOT FOUND".freeze,
|
143
|
+
# The standard empty 408 response for requests that timed out.
|
144
|
+
408 => "HTTP/1.1 408 Request Timeout\r\nConnection: close\r\nServer: Puma #{PUMA_VERSION}\r\n\r\n".freeze,
|
145
|
+
# Indicate that there was an internal error, obviously.
|
146
|
+
500 => "HTTP/1.1 500 Internal Server Error\r\n\r\n".freeze,
|
147
|
+
# A common header for indicating the server is too busy. Not used yet.
|
148
|
+
503 => "HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY".freeze
|
149
|
+
}
|
144
150
|
|
145
151
|
# The basic max request size we'll try to read.
|
146
152
|
CHUNK_SIZE = 16 * 1024
|
@@ -158,6 +164,9 @@ module Puma
|
|
158
164
|
LINE_END = "\r\n".freeze
|
159
165
|
REMOTE_ADDR = "REMOTE_ADDR".freeze
|
160
166
|
HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR".freeze
|
167
|
+
HTTP_X_FORWARDED_SSL = "HTTP_X_FORWARDED_SSL".freeze
|
168
|
+
HTTP_X_FORWARDED_SCHEME = "HTTP_X_FORWARDED_SCHEME".freeze
|
169
|
+
HTTP_X_FORWARDED_PROTO = "HTTP_X_FORWARDED_PROTO".freeze
|
161
170
|
|
162
171
|
SERVER_NAME = "SERVER_NAME".freeze
|
163
172
|
SERVER_PORT = "SERVER_PORT".freeze
|
@@ -219,11 +228,16 @@ module Puma
|
|
219
228
|
COLON = ": ".freeze
|
220
229
|
|
221
230
|
NEWLINE = "\n".freeze
|
231
|
+
HTTP_INJECTION_REGEX = /[\r\n]/.freeze
|
222
232
|
|
223
233
|
HIJACK_P = "rack.hijack?".freeze
|
224
234
|
HIJACK = "rack.hijack".freeze
|
225
235
|
HIJACK_IO = "rack.hijack_io".freeze
|
226
236
|
|
227
237
|
EARLY_HINTS = "rack.early_hints".freeze
|
238
|
+
|
239
|
+
# Mininum interval to checks worker health
|
240
|
+
WORKER_CHECK_INTERVAL = 5
|
241
|
+
|
228
242
|
end
|
229
243
|
end
|
data/lib/puma/control_cli.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'optparse'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
require_relative 'state_file'
|
5
|
+
require_relative 'const'
|
6
|
+
require_relative 'detect'
|
7
|
+
require_relative 'configuration'
|
6
8
|
require 'uri'
|
7
9
|
require 'socket'
|
8
10
|
|
@@ -20,6 +22,7 @@ module Puma
|
|
20
22
|
@control_auth_token = nil
|
21
23
|
@config_file = nil
|
22
24
|
@command = nil
|
25
|
+
@environment = ENV['RACK_ENV']
|
23
26
|
|
24
27
|
@argv = argv.dup
|
25
28
|
@stdout = stdout
|
@@ -57,6 +60,11 @@ module Puma
|
|
57
60
|
@config_file = arg
|
58
61
|
end
|
59
62
|
|
63
|
+
o.on "-e", "--environment ENVIRONMENT",
|
64
|
+
"The environment to run the Rack app on (default development)" do |arg|
|
65
|
+
@environment = arg
|
66
|
+
end
|
67
|
+
|
60
68
|
o.on_tail("-H", "--help", "Show this message") do
|
61
69
|
@stdout.puts o
|
62
70
|
exit
|
@@ -74,8 +82,12 @@ module Puma
|
|
74
82
|
@command = argv.shift
|
75
83
|
|
76
84
|
unless @config_file == '-'
|
77
|
-
|
78
|
-
|
85
|
+
environment = @environment || 'development'
|
86
|
+
|
87
|
+
if @config_file.nil?
|
88
|
+
@config_file = %W(config/puma/#{environment}.rb config/puma.rb).find do |f|
|
89
|
+
File.exist?(f)
|
90
|
+
end
|
79
91
|
end
|
80
92
|
|
81
93
|
if @config_file
|
@@ -99,7 +111,6 @@ module Puma
|
|
99
111
|
|
100
112
|
rescue => e
|
101
113
|
@stdout.puts e.message
|
102
|
-
@stdout.puts e.backtrace
|
103
114
|
exit 1
|
104
115
|
end
|
105
116
|
|
@@ -121,7 +132,7 @@ module Puma
|
|
121
132
|
@pid = sf.pid
|
122
133
|
elsif @pidfile
|
123
134
|
# get pid from pid_file
|
124
|
-
|
135
|
+
File.open(@pidfile) { |f| @pid = f.read.to_i }
|
125
136
|
end
|
126
137
|
end
|
127
138
|
|
@@ -129,7 +140,13 @@ module Puma
|
|
129
140
|
uri = URI.parse @control_url
|
130
141
|
|
131
142
|
# create server object by scheme
|
132
|
-
|
143
|
+
server = case uri.scheme
|
144
|
+
when "ssl"
|
145
|
+
require 'openssl'
|
146
|
+
OpenSSL::SSL::SSLSocket.new(
|
147
|
+
TCPSocket.new(uri.host, uri.port),
|
148
|
+
OpenSSL::SSL::SSLContext.new
|
149
|
+
).tap(&:connect)
|
133
150
|
when "tcp"
|
134
151
|
TCPSocket.new uri.host, uri.port
|
135
152
|
when "unix"
|
@@ -147,9 +164,9 @@ module Puma
|
|
147
164
|
url = url + "?token=#{@control_auth_token}"
|
148
165
|
end
|
149
166
|
|
150
|
-
|
167
|
+
server << "GET #{url} HTTP/1.0\r\n\r\n"
|
151
168
|
|
152
|
-
unless data =
|
169
|
+
unless data = server.read
|
153
170
|
raise "Server closed connection before responding"
|
154
171
|
end
|
155
172
|
|
@@ -172,8 +189,8 @@ module Puma
|
|
172
189
|
message "Command #{@command} sent success"
|
173
190
|
message response.last if @command == "stats" || @command == "gc-stats"
|
174
191
|
end
|
175
|
-
|
176
|
-
|
192
|
+
ensure
|
193
|
+
server.close if server && !server.closed?
|
177
194
|
end
|
178
195
|
|
179
196
|
def send_signal
|
@@ -204,6 +221,16 @@ module Puma
|
|
204
221
|
when "phased-restart"
|
205
222
|
Process.kill "SIGUSR1", @pid
|
206
223
|
|
224
|
+
when "status"
|
225
|
+
begin
|
226
|
+
Process.kill 0, @pid
|
227
|
+
puts "Puma is started"
|
228
|
+
rescue Errno::ESRCH
|
229
|
+
raise "Puma is not running"
|
230
|
+
end
|
231
|
+
|
232
|
+
return
|
233
|
+
|
207
234
|
else
|
208
235
|
return
|
209
236
|
end
|
@@ -232,7 +259,6 @@ module Puma
|
|
232
259
|
|
233
260
|
rescue => e
|
234
261
|
message e.message
|
235
|
-
message e.backtrace
|
236
262
|
exit 1
|
237
263
|
end
|
238
264
|
|
@@ -248,6 +274,7 @@ module Puma
|
|
248
274
|
run_args += ["--control-url", @control_url] if @control_url
|
249
275
|
run_args += ["--control-token", @control_auth_token] if @control_auth_token
|
250
276
|
run_args += ["-C", @config_file] if @config_file
|
277
|
+
run_args += ["-e", @environment] if @environment
|
251
278
|
|
252
279
|
events = Puma::Events.new @stdout, @stderr
|
253
280
|
|