puma 6.6.1-java → 7.0.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/History.md +89 -4
- data/README.md +11 -24
- data/docs/fork_worker.md +5 -5
- data/docs/kubernetes.md +6 -4
- data/docs/restart.md +2 -2
- data/docs/signals.md +9 -9
- data/docs/stats.md +2 -1
- data/ext/puma_http11/extconf.rb +2 -17
- data/ext/puma_http11/mini_ssl.c +0 -5
- data/lib/puma/binder.rb +10 -8
- data/lib/puma/cli.rb +3 -5
- data/lib/puma/client.rb +31 -31
- data/lib/puma/cluster/worker.rb +9 -10
- data/lib/puma/cluster/worker_handle.rb +34 -5
- data/lib/puma/cluster.rb +12 -13
- data/lib/puma/commonlogger.rb +3 -3
- data/lib/puma/configuration.rb +86 -43
- data/lib/puma/const.rb +9 -10
- data/lib/puma/control_cli.rb +3 -2
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +108 -81
- data/lib/puma/error_logger.rb +3 -1
- data/lib/puma/events.rb +13 -13
- data/lib/puma/io_buffer.rb +8 -4
- data/lib/puma/launcher/bundle_pruner.rb +1 -1
- data/lib/puma/launcher.rb +28 -29
- data/lib/puma/minissl.rb +0 -1
- data/lib/puma/plugin/systemd.rb +3 -3
- data/lib/puma/rack/urlmap.rb +1 -1
- data/lib/puma/reactor.rb +19 -4
- data/lib/puma/request.rb +26 -23
- data/lib/puma/runner.rb +8 -17
- data/lib/puma/server.rb +80 -48
- data/lib/puma/single.rb +4 -1
- data/lib/puma/thread_pool.rb +27 -81
- data/lib/puma/util.rb +0 -7
- data/lib/puma.rb +10 -0
- data/lib/rack/handler/puma.rb +2 -2
- metadata +4 -4
data/lib/puma/cluster/worker.rb
CHANGED
@@ -110,7 +110,6 @@ module Puma
|
|
110
110
|
begin
|
111
111
|
@worker_write << "#{PIPE_BOOT}#{Process.pid}:#{index}\n"
|
112
112
|
rescue SystemCallError, IOError
|
113
|
-
Puma::Util.purge_interrupt_queue
|
114
113
|
STDERR.puts "Master seems to have exited, exiting."
|
115
114
|
return
|
116
115
|
end
|
@@ -128,16 +127,16 @@ module Puma
|
|
128
127
|
|
129
128
|
while true
|
130
129
|
begin
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
io << payload
|
130
|
+
payload = base_payload.dup
|
131
|
+
|
132
|
+
hsh = server.stats
|
133
|
+
hsh.each do |k, v|
|
134
|
+
payload << %Q! "#{k}":#{v || 0},!
|
135
|
+
end
|
136
|
+
# sub call properly adds 'closing' string
|
137
|
+
io << payload.sub(/,\z/, " }\n")
|
138
|
+
server.reset_max
|
139
139
|
rescue IOError
|
140
|
-
Puma::Util.purge_interrupt_queue
|
141
140
|
break
|
142
141
|
end
|
143
142
|
sleep @options[:worker_check_interval]
|
@@ -4,13 +4,15 @@ module Puma
|
|
4
4
|
class Cluster < Runner
|
5
5
|
#—————————————————————— DO NOT USE — this class is for internal use only ———
|
6
6
|
|
7
|
-
|
8
7
|
# This class represents a worker process from the perspective of the puma
|
9
8
|
# master process. It contains information about the process and its health
|
10
9
|
# and it exposes methods to control the process via IPC. It does not
|
11
10
|
# include the actual logic executed by the worker process itself. For that,
|
12
11
|
# see Puma::Cluster::Worker.
|
13
12
|
class WorkerHandle # :nodoc:
|
13
|
+
# array of stat 'max' keys
|
14
|
+
WORKER_MAX_KEYS = [:backlog_max, :reactor_max]
|
15
|
+
|
14
16
|
def initialize(idx, pid, phase, options)
|
15
17
|
@index = idx
|
16
18
|
@pid = pid
|
@@ -23,6 +25,7 @@ module Puma
|
|
23
25
|
@last_checkin = Time.now
|
24
26
|
@last_status = {}
|
25
27
|
@term = false
|
28
|
+
@worker_max = Array.new WORKER_MAX_KEYS.length, 0
|
26
29
|
end
|
27
30
|
|
28
31
|
attr_reader :index, :pid, :phase, :signal, :last_checkin, :last_status, :started_at
|
@@ -51,12 +54,38 @@ module Puma
|
|
51
54
|
@term
|
52
55
|
end
|
53
56
|
|
54
|
-
STATUS_PATTERN = /{ "backlog":(?<backlog>\d*), "running":(?<running>\d*), "pool_capacity":(?<pool_capacity>\d*), "max_threads":(?<max_threads>\d*), "requests_count":(?<requests_count>\d*), "busy_threads":(?<busy_threads>\d*) }/
|
55
|
-
private_constant :STATUS_PATTERN
|
56
|
-
|
57
57
|
def ping!(status)
|
58
|
+
hsh = {}
|
59
|
+
k, v = nil, nil
|
60
|
+
status.tr('}{"', '').strip.split(", ") do |kv|
|
61
|
+
cntr = 0
|
62
|
+
kv.split(':') do |t|
|
63
|
+
if cntr == 0
|
64
|
+
k = t
|
65
|
+
cntr = 1
|
66
|
+
else
|
67
|
+
v = t
|
68
|
+
end
|
69
|
+
end
|
70
|
+
hsh[k.to_sym] = v.to_i
|
71
|
+
end
|
72
|
+
|
73
|
+
# check stat max values, we can't signal workers to reset the max values,
|
74
|
+
# so we do so here
|
75
|
+
WORKER_MAX_KEYS.each_with_index do |key, idx|
|
76
|
+
if hsh[key] < @worker_max[idx]
|
77
|
+
hsh[key] = @worker_max[idx]
|
78
|
+
else
|
79
|
+
@worker_max[idx] = hsh[key]
|
80
|
+
end
|
81
|
+
end
|
58
82
|
@last_checkin = Time.now
|
59
|
-
@last_status =
|
83
|
+
@last_status = hsh
|
84
|
+
end
|
85
|
+
|
86
|
+
# Resets max values to zero. Called whenever `Cluster#stats` is called
|
87
|
+
def reset_max
|
88
|
+
WORKER_MAX_KEYS.length.times { |idx| @worker_max[idx] = 0 }
|
60
89
|
end
|
61
90
|
|
62
91
|
# @see Puma::Cluster#check_workers
|
data/lib/puma/cluster.rb
CHANGED
@@ -22,6 +22,7 @@ module Puma
|
|
22
22
|
@workers = []
|
23
23
|
@next_check = Time.now
|
24
24
|
|
25
|
+
@worker_max = [] # keeps track of 'max' stat values
|
25
26
|
@phased_restart = false
|
26
27
|
end
|
27
28
|
|
@@ -45,8 +46,7 @@ module Puma
|
|
45
46
|
end
|
46
47
|
|
47
48
|
def start_phased_restart(refork = false)
|
48
|
-
@events.
|
49
|
-
|
49
|
+
@events.fire_before_restart!
|
50
50
|
@phase += 1
|
51
51
|
if refork
|
52
52
|
log "- Starting worker refork, phase: #{@phase}"
|
@@ -268,11 +268,14 @@ module Puma
|
|
268
268
|
end
|
269
269
|
|
270
270
|
# Inside of a child process, this will return all zeroes, as @workers is only populated in
|
271
|
-
# the master process.
|
271
|
+
# the master process. Calling this also resets stat 'max' values to zero.
|
272
272
|
# @!attribute [r] stats
|
273
|
+
# @return [Hash]
|
274
|
+
|
273
275
|
def stats
|
274
276
|
old_worker_count = @workers.count { |w| w.phase != @phase }
|
275
277
|
worker_status = @workers.map do |w|
|
278
|
+
w.reset_max
|
276
279
|
{
|
277
280
|
started_at: utc_iso8601(w.started_at),
|
278
281
|
pid: w.pid,
|
@@ -283,7 +286,6 @@ module Puma
|
|
283
286
|
last_status: w.last_status,
|
284
287
|
}
|
285
288
|
end
|
286
|
-
|
287
289
|
{
|
288
290
|
started_at: utc_iso8601(@started_at),
|
289
291
|
workers: @workers.size,
|
@@ -352,7 +354,7 @@ module Puma
|
|
352
354
|
|
353
355
|
stop_workers
|
354
356
|
stop
|
355
|
-
@events.
|
357
|
+
@events.fire_after_stopped!
|
356
358
|
raise(SignalException, "SIGTERM") if @options[:raise_exception_on_sigterm]
|
357
359
|
exit 0 # Clean exit, workers were stopped
|
358
360
|
end
|
@@ -369,12 +371,8 @@ module Puma
|
|
369
371
|
|
370
372
|
if preload?
|
371
373
|
# Threads explicitly marked as fork safe will be ignored. Used in Rails,
|
372
|
-
# but may be used by anyone.
|
373
|
-
|
374
|
-
# where calling thread_variable_get on a Process::Waiter will segfault.
|
375
|
-
# We can drop that clause once those versions of Ruby are no longer
|
376
|
-
# supported.
|
377
|
-
fork_safe = ->(t) { !t.is_a?(Process::Waiter) && t.thread_variable_get(:fork_safe) }
|
374
|
+
# but may be used by anyone.
|
375
|
+
fork_safe = ->(t) { t.thread_variable_get(:fork_safe) }
|
378
376
|
|
379
377
|
before = Thread.list.reject(&fork_safe)
|
380
378
|
|
@@ -423,6 +421,7 @@ module Puma
|
|
423
421
|
|
424
422
|
log "Use Ctrl-C to stop"
|
425
423
|
|
424
|
+
warn_ruby_mn_threads
|
426
425
|
single_worker_warning
|
427
426
|
|
428
427
|
redirect_io
|
@@ -511,7 +510,7 @@ module Puma
|
|
511
510
|
end
|
512
511
|
|
513
512
|
if !booted && @workers.none? {|worker| worker.last_status.empty?}
|
514
|
-
@events.
|
513
|
+
@events.fire_after_booted!
|
515
514
|
debug_loaded_extensions("Loaded Extensions - master:") if @log_writer.debug?
|
516
515
|
booted = true
|
517
516
|
end
|
@@ -528,7 +527,7 @@ module Puma
|
|
528
527
|
end
|
529
528
|
|
530
529
|
if in_phased_restart && workers_not_booted.zero?
|
531
|
-
@events.
|
530
|
+
@events.fire_after_booted!
|
532
531
|
debug_loaded_extensions("Loaded Extensions - master:") if @log_writer.debug?
|
533
532
|
in_phased_restart = false
|
534
533
|
end
|
data/lib/puma/commonlogger.rb
CHANGED
@@ -29,13 +29,13 @@ module Puma
|
|
29
29
|
|
30
30
|
CONTENT_LENGTH = 'Content-Length' # should be lower case from app,
|
31
31
|
# Util::HeaderHash allows mixed
|
32
|
-
HTTP_VERSION = Const::HTTP_VERSION
|
33
32
|
HTTP_X_FORWARDED_FOR = Const::HTTP_X_FORWARDED_FOR
|
34
33
|
PATH_INFO = Const::PATH_INFO
|
35
34
|
QUERY_STRING = Const::QUERY_STRING
|
36
35
|
REMOTE_ADDR = Const::REMOTE_ADDR
|
37
36
|
REMOTE_USER = 'REMOTE_USER'
|
38
37
|
REQUEST_METHOD = Const::REQUEST_METHOD
|
38
|
+
SERVER_PROTOCOL = Const::SERVER_PROTOCOL
|
39
39
|
|
40
40
|
def initialize(app, logger=nil)
|
41
41
|
@app = app
|
@@ -70,7 +70,7 @@ module Puma
|
|
70
70
|
env[REQUEST_METHOD],
|
71
71
|
env[PATH_INFO],
|
72
72
|
env[QUERY_STRING].empty? ? "" : "?#{env[QUERY_STRING]}",
|
73
|
-
env[
|
73
|
+
env[SERVER_PROTOCOL],
|
74
74
|
now - began_at ]
|
75
75
|
|
76
76
|
write(msg)
|
@@ -87,7 +87,7 @@ module Puma
|
|
87
87
|
env[REQUEST_METHOD],
|
88
88
|
env[PATH_INFO],
|
89
89
|
env[QUERY_STRING].empty? ? "" : "?#{env[QUERY_STRING]}",
|
90
|
-
env[
|
90
|
+
env[SERVER_PROTOCOL],
|
91
91
|
status.to_s[0..3],
|
92
92
|
length,
|
93
93
|
now - began_at ]
|
data/lib/puma/configuration.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require_relative 'plugin'
|
4
4
|
require_relative 'const'
|
5
5
|
require_relative 'dsl'
|
6
|
+
require_relative 'events'
|
6
7
|
|
7
8
|
module Puma
|
8
9
|
# A class used for storing "leveled" configuration options.
|
@@ -112,7 +113,7 @@ module Puma
|
|
112
113
|
# config = Configuration.new({}) do |user_config, file_config, default_config|
|
113
114
|
# user_config.port 3003
|
114
115
|
# end
|
115
|
-
# config.
|
116
|
+
# config.clamp
|
116
117
|
# puts config.options[:port]
|
117
118
|
# # => 3003
|
118
119
|
#
|
@@ -125,10 +126,13 @@ module Puma
|
|
125
126
|
# is done because an environment variable may have been modified while loading
|
126
127
|
# configuration files.
|
127
128
|
class Configuration
|
129
|
+
class NotLoadedError < StandardError; end
|
130
|
+
class NotClampedError < StandardError; end
|
131
|
+
|
128
132
|
DEFAULTS = {
|
129
133
|
auto_trim_time: 30,
|
130
134
|
binds: ['tcp://0.0.0.0:9292'.freeze],
|
131
|
-
|
135
|
+
fiber_per_request: !!ENV.fetch("PUMA_FIBER_PER_REQUEST", false),
|
132
136
|
debug: false,
|
133
137
|
enable_keep_alives: true,
|
134
138
|
early_hints: nil,
|
@@ -140,19 +144,17 @@ module Puma
|
|
140
144
|
io_selector_backend: :auto,
|
141
145
|
log_requests: false,
|
142
146
|
logger: STDOUT,
|
143
|
-
#
|
144
|
-
#
|
145
|
-
#
|
146
|
-
|
147
|
-
# well behaved client from monopolizing the thread forever.
|
148
|
-
max_fast_inline: 10,
|
147
|
+
# Limits how many requests a keep alive connection can make.
|
148
|
+
# The connection will be closed after it reaches `max_keep_alive`
|
149
|
+
# requests.
|
150
|
+
max_keep_alive: 999,
|
149
151
|
max_threads: Puma.mri? ? 5 : 16,
|
150
152
|
min_threads: 0,
|
151
153
|
mode: :http,
|
152
154
|
mutate_stdout_and_stderr_to_sync_on_write: true,
|
153
155
|
out_of_band: [],
|
154
156
|
# Number of seconds for another request within a persistent session.
|
155
|
-
persistent_timeout:
|
157
|
+
persistent_timeout: ENV.fetch('PUMA_PERSISTENT_TIMEOUT', 65),
|
156
158
|
queue_requests: true,
|
157
159
|
rackup: 'config.ru'.freeze,
|
158
160
|
raise_exception_on_sigterm: true,
|
@@ -176,24 +178,31 @@ module Puma
|
|
176
178
|
def initialize(user_options={}, default_options = {}, env = ENV, &block)
|
177
179
|
default_options = self.puma_default_options(env).merge(default_options)
|
178
180
|
|
179
|
-
@
|
181
|
+
@_options = UserFileDefaultOptions.new(user_options, default_options)
|
180
182
|
@plugins = PluginLoader.new
|
181
|
-
@
|
182
|
-
@
|
183
|
-
@
|
184
|
-
|
185
|
-
|
186
|
-
default_options[:preload_app] = (@options[:workers] > 1) && Puma.forkable?
|
187
|
-
end
|
183
|
+
@events = @_options[:events] || Events.new
|
184
|
+
@hooks = {}
|
185
|
+
@user_dsl = DSL.new(@_options.user_options, self)
|
186
|
+
@file_dsl = DSL.new(@_options.file_options, self)
|
187
|
+
@default_dsl = DSL.new(@_options.default_options, self)
|
188
188
|
|
189
189
|
@puma_bundler_pruned = env.key? 'PUMA_BUNDLER_PRUNED'
|
190
190
|
|
191
191
|
if block
|
192
192
|
configure(&block)
|
193
193
|
end
|
194
|
+
|
195
|
+
@loaded = false
|
196
|
+
@clamped = false
|
194
197
|
end
|
195
198
|
|
196
|
-
attr_reader :
|
199
|
+
attr_reader :plugins, :events, :hooks
|
200
|
+
|
201
|
+
def options
|
202
|
+
raise NotClampedError, "ensure clamp is called before accessing options" unless @clamped
|
203
|
+
|
204
|
+
@_options
|
205
|
+
end
|
197
206
|
|
198
207
|
def configure
|
199
208
|
yield @user_dsl, @file_dsl, @default_dsl
|
@@ -206,7 +215,7 @@ module Puma
|
|
206
215
|
def initialize_copy(other)
|
207
216
|
@conf = nil
|
208
217
|
@cli_options = nil
|
209
|
-
@
|
218
|
+
@_options = @_options.dup
|
210
219
|
end
|
211
220
|
|
212
221
|
def flatten
|
@@ -214,7 +223,7 @@ module Puma
|
|
214
223
|
end
|
215
224
|
|
216
225
|
def flatten!
|
217
|
-
@
|
226
|
+
@_options = @_options.flatten
|
218
227
|
self
|
219
228
|
end
|
220
229
|
|
@@ -243,18 +252,20 @@ module Puma
|
|
243
252
|
end
|
244
253
|
|
245
254
|
def load
|
255
|
+
@loaded = true
|
246
256
|
config_files.each { |config_file| @file_dsl._load_from(config_file) }
|
247
|
-
|
248
|
-
@options
|
257
|
+
@_options
|
249
258
|
end
|
250
259
|
|
251
260
|
def config_files
|
252
|
-
|
261
|
+
raise NotLoadedError, "ensure load is called before accessing config_files" unless @loaded
|
262
|
+
|
263
|
+
files = @_options.all_of(:config_files)
|
253
264
|
|
254
265
|
return [] if files == ['-']
|
255
266
|
return files if files.any?
|
256
267
|
|
257
|
-
first_default_file = %W(config/puma/#{@
|
268
|
+
first_default_file = %W(config/puma/#{@_options[:environment]}.rb config/puma.rb).find do |f|
|
258
269
|
File.exist?(f)
|
259
270
|
end
|
260
271
|
|
@@ -262,9 +273,16 @@ module Puma
|
|
262
273
|
end
|
263
274
|
|
264
275
|
# Call once all configuration (included from rackup files)
|
265
|
-
# is loaded to
|
276
|
+
# is loaded to finalize defaults and lock in the configuration.
|
277
|
+
#
|
278
|
+
# This also calls load if it hasn't been called yet.
|
266
279
|
def clamp
|
267
|
-
@
|
280
|
+
load unless @loaded
|
281
|
+
set_conditional_default_options
|
282
|
+
@_options.finalize_values
|
283
|
+
@clamped = true
|
284
|
+
warn_hooks
|
285
|
+
options
|
268
286
|
end
|
269
287
|
|
270
288
|
# Injects the Configuration object into the env
|
@@ -283,11 +301,11 @@ module Puma
|
|
283
301
|
# Indicate if there is a properly configured app
|
284
302
|
#
|
285
303
|
def app_configured?
|
286
|
-
|
304
|
+
options[:app] || File.exist?(rackup)
|
287
305
|
end
|
288
306
|
|
289
307
|
def rackup
|
290
|
-
|
308
|
+
options[:rackup]
|
291
309
|
end
|
292
310
|
|
293
311
|
# Load the specified rackup file, pull options from
|
@@ -296,9 +314,9 @@ module Puma
|
|
296
314
|
def app
|
297
315
|
found = options[:app] || load_rackup
|
298
316
|
|
299
|
-
if
|
317
|
+
if options[:log_requests]
|
300
318
|
require_relative 'commonlogger'
|
301
|
-
logger =
|
319
|
+
logger = options[:custom_logger] ? options[:custom_logger] : options[:logger]
|
302
320
|
found = CommonLogger.new(found, logger)
|
303
321
|
end
|
304
322
|
|
@@ -307,7 +325,7 @@ module Puma
|
|
307
325
|
|
308
326
|
# Return which environment we're running in
|
309
327
|
def environment
|
310
|
-
|
328
|
+
options[:environment]
|
311
329
|
end
|
312
330
|
|
313
331
|
def load_plugin(name)
|
@@ -315,18 +333,19 @@ module Puma
|
|
315
333
|
end
|
316
334
|
|
317
335
|
# @param key [:Symbol] hook to run
|
318
|
-
# @param arg [Launcher, Int] `:
|
336
|
+
# @param arg [Launcher, Int] `:before_restart` passes Launcher
|
319
337
|
#
|
320
338
|
def run_hooks(key, arg, log_writer, hook_data = nil)
|
321
339
|
log_writer.debug "Running #{key} hooks"
|
322
340
|
|
323
|
-
|
341
|
+
options.all_of(key).each do |hook_options|
|
324
342
|
begin
|
325
|
-
|
326
|
-
|
327
|
-
|
343
|
+
block = hook_options[:block]
|
344
|
+
if id = hook_options[:id]
|
345
|
+
hook_data[id] ||= Hash.new
|
346
|
+
block.call arg, hook_data[id]
|
328
347
|
else
|
329
|
-
|
348
|
+
block.call arg
|
330
349
|
end
|
331
350
|
rescue => e
|
332
351
|
log_writer.log "WARNING hook #{key} failed with exception (#{e.class}) #{e.message}"
|
@@ -336,7 +355,7 @@ module Puma
|
|
336
355
|
end
|
337
356
|
|
338
357
|
def final_options
|
339
|
-
|
358
|
+
options.final_options
|
340
359
|
end
|
341
360
|
|
342
361
|
def self.temp_path
|
@@ -346,6 +365,12 @@ module Puma
|
|
346
365
|
"#{Dir.tmpdir}/puma-status-#{t}-#{$$}"
|
347
366
|
end
|
348
367
|
|
368
|
+
def self.random_token
|
369
|
+
require 'securerandom' unless defined?(SecureRandom)
|
370
|
+
|
371
|
+
SecureRandom.hex(16)
|
372
|
+
end
|
373
|
+
|
349
374
|
private
|
350
375
|
|
351
376
|
def require_processor_counter
|
@@ -386,22 +411,40 @@ module Puma
|
|
386
411
|
rack_app, rack_options = rack_builder.parse_file(rackup)
|
387
412
|
rack_options = rack_options || {}
|
388
413
|
|
389
|
-
|
414
|
+
options.file_options.merge!(rack_options)
|
390
415
|
|
391
416
|
config_ru_binds = []
|
392
417
|
rack_options.each do |k, v|
|
393
418
|
config_ru_binds << v if k.to_s.start_with?("bind")
|
394
419
|
end
|
395
420
|
|
396
|
-
|
421
|
+
options.file_options[:binds] = config_ru_binds unless config_ru_binds.empty?
|
397
422
|
|
398
423
|
rack_app
|
399
424
|
end
|
400
425
|
|
401
|
-
def
|
402
|
-
|
426
|
+
def set_conditional_default_options
|
427
|
+
@_options.default_options[:preload_app] = !@_options[:prune_bundler] &&
|
428
|
+
(@_options[:workers] > 1) && Puma.forkable?
|
429
|
+
end
|
403
430
|
|
404
|
-
|
431
|
+
def warn_hooks
|
432
|
+
return if options[:workers] > 0
|
433
|
+
return if options[:silence_fork_callback_warning]
|
434
|
+
|
435
|
+
log_writer = LogWriter.stdio
|
436
|
+
@hooks.each_key do |hook|
|
437
|
+
options.all_of(hook).each do |hook_options|
|
438
|
+
next unless hook_options[:cluster_only]
|
439
|
+
|
440
|
+
log_writer.log(<<~MSG.tr("\n", " "))
|
441
|
+
Warning: The code in the `#{hook}` block will not execute
|
442
|
+
in the current Puma configuration. The `#{hook}` block only
|
443
|
+
executes in Puma's cluster mode. To fix this, either remove the
|
444
|
+
`#{hook}` call or increase Puma's worker count above zero.
|
445
|
+
MSG
|
446
|
+
end
|
447
|
+
end
|
405
448
|
end
|
406
449
|
end
|
407
450
|
end
|
data/lib/puma/const.rb
CHANGED
@@ -100,13 +100,11 @@ module Puma
|
|
100
100
|
# too taxing on performance.
|
101
101
|
module Const
|
102
102
|
|
103
|
-
PUMA_VERSION = VERSION = "
|
104
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "7.0.0"
|
104
|
+
CODE_NAME = "Romantic Warrior"
|
105
105
|
|
106
106
|
PUMA_SERVER_STRING = ["puma", PUMA_VERSION, CODE_NAME].join(" ").freeze
|
107
107
|
|
108
|
-
FAST_TRACK_KA_TIMEOUT = 0.2
|
109
|
-
|
110
108
|
# How long to wait when getting some write blocking on the socket when
|
111
109
|
# sending data back
|
112
110
|
WRITE_TIMEOUT = 10
|
@@ -125,9 +123,9 @@ module Puma
|
|
125
123
|
# Indicate that we couldn't parse the request
|
126
124
|
400 => "HTTP/1.1 400 Bad Request\r\n\r\n",
|
127
125
|
# The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
|
128
|
-
404 => "HTTP/1.1 404 Not Found\r\
|
126
|
+
404 => "HTTP/1.1 404 Not Found\r\nconnection: close\r\n\r\n",
|
129
127
|
# The standard empty 408 response for requests that timed out.
|
130
|
-
408 => "HTTP/1.1 408 Request Timeout\r\
|
128
|
+
408 => "HTTP/1.1 408 Request Timeout\r\nconnection: close\r\n\r\n",
|
131
129
|
# Indicate that there was an internal error, obviously.
|
132
130
|
500 => "HTTP/1.1 500 Internal Server Error\r\n\r\n",
|
133
131
|
# Incorrect or invalid header value
|
@@ -230,6 +228,7 @@ module Puma
|
|
230
228
|
RACK_INPUT = "rack.input"
|
231
229
|
RACK_URL_SCHEME = "rack.url_scheme"
|
232
230
|
RACK_AFTER_REPLY = "rack.after_reply"
|
231
|
+
RACK_RESPONSE_FINISHED = "rack.response_finished"
|
233
232
|
PUMA_SOCKET = "puma.socket"
|
234
233
|
PUMA_CONFIG = "puma.config"
|
235
234
|
PUMA_PEERCERT = "puma.peercert"
|
@@ -252,14 +251,14 @@ module Puma
|
|
252
251
|
KEEP_ALIVE = "keep-alive"
|
253
252
|
|
254
253
|
CONTENT_LENGTH2 = "content-length"
|
255
|
-
CONTENT_LENGTH_S = "
|
254
|
+
CONTENT_LENGTH_S = "content-length: "
|
256
255
|
TRANSFER_ENCODING = "transfer-encoding"
|
257
256
|
TRANSFER_ENCODING2 = "HTTP_TRANSFER_ENCODING"
|
258
257
|
|
259
|
-
CONNECTION_CLOSE = "
|
260
|
-
CONNECTION_KEEP_ALIVE = "
|
258
|
+
CONNECTION_CLOSE = "connection: close\r\n"
|
259
|
+
CONNECTION_KEEP_ALIVE = "connection: keep-alive\r\n"
|
261
260
|
|
262
|
-
TRANSFER_ENCODING_CHUNKED = "
|
261
|
+
TRANSFER_ENCODING_CHUNKED = "transfer-encoding: chunked\r\n"
|
263
262
|
CLOSE_CHUNKED = "0\r\n\r\n"
|
264
263
|
|
265
264
|
CHUNKED = "chunked"
|
data/lib/puma/control_cli.rb
CHANGED
@@ -128,7 +128,8 @@ module Puma
|
|
128
128
|
require_relative 'log_writer'
|
129
129
|
|
130
130
|
config = Puma::Configuration.new({ config_files: [@config_file] }, {} , env)
|
131
|
-
config.
|
131
|
+
config.clamp
|
132
|
+
|
132
133
|
@state ||= config.options[:state]
|
133
134
|
@control_url ||= config.options[:control_url]
|
134
135
|
@control_auth_token ||= config.options[:control_auth_token]
|
@@ -248,7 +249,7 @@ module Puma
|
|
248
249
|
@stdout.flush unless @stdout.sync
|
249
250
|
return
|
250
251
|
elsif sig.start_with? 'SIG'
|
251
|
-
if Signal.list.key? sig.
|
252
|
+
if Signal.list.key? sig.delete_prefix('SIG')
|
252
253
|
Process.kill sig, @pid
|
253
254
|
else
|
254
255
|
raise "Signal '#{sig}' not available'"
|