puma 5.5.2 → 6.3.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 +4 -4
- data/History.md +336 -3
- data/README.md +61 -16
- data/bin/puma-wild +1 -1
- data/docs/architecture.md +4 -4
- data/docs/compile_options.md +34 -0
- data/docs/fork_worker.md +1 -3
- data/docs/nginx.md +1 -1
- data/docs/signals.md +1 -0
- data/docs/systemd.md +1 -2
- data/docs/testing_benchmarks_local_files.md +150 -0
- data/docs/testing_test_rackup_ci_files.md +36 -0
- data/ext/puma_http11/extconf.rb +28 -14
- data/ext/puma_http11/http11_parser.c +1 -1
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +2 -2
- data/ext/puma_http11/http11_parser.rl +2 -2
- data/ext/puma_http11/http11_parser_common.rl +2 -2
- data/ext/puma_http11/mini_ssl.c +135 -23
- data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +188 -102
- data/ext/puma_http11/puma_http11.c +18 -10
- data/lib/puma/app/status.rb +7 -4
- data/lib/puma/binder.rb +62 -51
- data/lib/puma/cli.rb +19 -20
- data/lib/puma/client.rb +108 -26
- data/lib/puma/cluster/worker.rb +23 -16
- data/lib/puma/cluster/worker_handle.rb +8 -1
- data/lib/puma/cluster.rb +62 -41
- data/lib/puma/commonlogger.rb +21 -14
- data/lib/puma/configuration.rb +76 -55
- data/lib/puma/const.rb +133 -97
- data/lib/puma/control_cli.rb +21 -18
- data/lib/puma/detect.rb +12 -2
- data/lib/puma/dsl.rb +270 -55
- data/lib/puma/error_logger.rb +18 -9
- data/lib/puma/events.rb +6 -126
- data/lib/puma/io_buffer.rb +39 -4
- data/lib/puma/jruby_restart.rb +2 -1
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +114 -175
- data/lib/puma/log_writer.rb +147 -0
- data/lib/puma/minissl/context_builder.rb +30 -16
- data/lib/puma/minissl.rb +126 -17
- data/lib/puma/null_io.rb +5 -0
- data/lib/puma/plugin/systemd.rb +90 -0
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/plugin.rb +1 -1
- data/lib/puma/rack/builder.rb +6 -6
- data/lib/puma/rack_default.rb +19 -4
- data/lib/puma/reactor.rb +19 -10
- data/lib/puma/request.rb +365 -161
- data/lib/puma/runner.rb +55 -22
- data/lib/puma/sd_notify.rb +149 -0
- data/lib/puma/server.rb +91 -94
- data/lib/puma/single.rb +13 -11
- data/lib/puma/state_file.rb +39 -7
- data/lib/puma/thread_pool.rb +25 -21
- data/lib/puma/util.rb +12 -14
- data/lib/puma.rb +12 -11
- data/lib/rack/handler/puma.rb +113 -86
- data/tools/Dockerfile +1 -1
- metadata +11 -6
- data/lib/puma/queue_close.rb +0 -26
- data/lib/puma/systemd.rb +0 -46
data/lib/puma/single.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require_relative 'runner'
|
4
|
+
require_relative 'detect'
|
5
|
+
require_relative 'plugin'
|
6
6
|
|
7
7
|
module Puma
|
8
8
|
# This class is instantiated by the `Puma::Launcher` and used
|
@@ -16,26 +16,26 @@ module Puma
|
|
16
16
|
# @!attribute [r] stats
|
17
17
|
def stats
|
18
18
|
{
|
19
|
-
started_at: @started_at
|
20
|
-
}.merge(@server.stats)
|
19
|
+
started_at: utc_iso8601(@started_at)
|
20
|
+
}.merge(@server.stats).merge(super)
|
21
21
|
end
|
22
22
|
|
23
23
|
def restart
|
24
|
-
@server
|
24
|
+
@server&.begin_restart
|
25
25
|
end
|
26
26
|
|
27
27
|
def stop
|
28
|
-
@server
|
28
|
+
@server&.stop false
|
29
29
|
end
|
30
30
|
|
31
31
|
def halt
|
32
|
-
@server
|
32
|
+
@server&.halt
|
33
33
|
end
|
34
34
|
|
35
35
|
def stop_blocked
|
36
36
|
log "- Gracefully stopping, waiting for requests to finish"
|
37
|
-
@control
|
38
|
-
@server
|
37
|
+
@control&.stop true
|
38
|
+
@server&.stop true
|
39
39
|
end
|
40
40
|
|
41
41
|
def run
|
@@ -55,7 +55,9 @@ module Puma
|
|
55
55
|
log "Use Ctrl-C to stop"
|
56
56
|
redirect_io
|
57
57
|
|
58
|
-
@
|
58
|
+
@events.fire_on_booted!
|
59
|
+
|
60
|
+
debug_loaded_extensions("Loaded Extensions:") if @log_writer.debug?
|
59
61
|
|
60
62
|
begin
|
61
63
|
server_thread.join
|
data/lib/puma/state_file.rb
CHANGED
@@ -1,15 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'yaml'
|
4
|
-
|
5
3
|
module Puma
|
4
|
+
|
5
|
+
# Puma::Launcher uses StateFile to write a yaml file for use with Puma::ControlCLI.
|
6
|
+
#
|
7
|
+
# In previous versions of Puma, YAML was used to read/write the state file.
|
8
|
+
# Since Puma is similar to Bundler/RubyGems in that it may load before one's app
|
9
|
+
# does, minimizing the dependencies that may be shared with the app is desired.
|
10
|
+
#
|
11
|
+
# At present, it only works with numeric and string values. It is still a valid
|
12
|
+
# yaml file, and the CI tests parse it with Psych.
|
13
|
+
#
|
6
14
|
class StateFile
|
15
|
+
|
16
|
+
ALLOWED_FIELDS = %w!control_url control_auth_token pid running_from!
|
17
|
+
|
7
18
|
def initialize
|
8
19
|
@options = {}
|
9
20
|
end
|
10
21
|
|
11
22
|
def save(path, permission = nil)
|
12
|
-
contents =
|
23
|
+
contents = +"---\n"
|
24
|
+
@options.each do |k,v|
|
25
|
+
next unless ALLOWED_FIELDS.include? k
|
26
|
+
case v
|
27
|
+
when Numeric
|
28
|
+
contents << "#{k}: #{v}\n"
|
29
|
+
when String
|
30
|
+
next if v.strip.empty?
|
31
|
+
contents << (k == 'running_from' || v.to_s.include?(' ') ?
|
32
|
+
"#{k}: \"#{v}\"\n" : "#{k}: #{v}\n")
|
33
|
+
end
|
34
|
+
end
|
13
35
|
if permission
|
14
36
|
File.write path, contents, mode: 'wb:UTF-8'
|
15
37
|
else
|
@@ -18,12 +40,22 @@ module Puma
|
|
18
40
|
end
|
19
41
|
|
20
42
|
def load(path)
|
21
|
-
|
43
|
+
File.read(path).lines.each do |line|
|
44
|
+
next if line.start_with? '#'
|
45
|
+
k,v = line.split ':', 2
|
46
|
+
next unless v && ALLOWED_FIELDS.include?(k)
|
47
|
+
v = v.strip
|
48
|
+
@options[k] =
|
49
|
+
case v
|
50
|
+
when '' then nil
|
51
|
+
when /\A\d+\z/ then v.to_i
|
52
|
+
when /\A\d+\.\d+\z/ then v.to_f
|
53
|
+
else v.gsub(/\A"|"\z/, '')
|
54
|
+
end
|
55
|
+
end
|
22
56
|
end
|
23
57
|
|
24
|
-
|
25
|
-
|
26
|
-
FIELDS.each do |f|
|
58
|
+
ALLOWED_FIELDS.each do |f|
|
27
59
|
define_method f do
|
28
60
|
@options[f]
|
29
61
|
end
|
data/lib/puma/thread_pool.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'thread'
|
4
4
|
|
5
|
+
require_relative 'io_buffer'
|
6
|
+
|
5
7
|
module Puma
|
6
8
|
# Internal Docs for A simple thread pool management object.
|
7
9
|
#
|
@@ -29,7 +31,7 @@ module Puma
|
|
29
31
|
# The block passed is the work that will be performed in each
|
30
32
|
# thread.
|
31
33
|
#
|
32
|
-
def initialize(name,
|
34
|
+
def initialize(name, options = {}, &block)
|
33
35
|
@not_empty = ConditionVariable.new
|
34
36
|
@not_full = ConditionVariable.new
|
35
37
|
@mutex = Mutex.new
|
@@ -40,10 +42,17 @@ module Puma
|
|
40
42
|
@waiting = 0
|
41
43
|
|
42
44
|
@name = name
|
43
|
-
@min = Integer(
|
44
|
-
@max = Integer(
|
45
|
+
@min = Integer(options[:min_threads])
|
46
|
+
@max = Integer(options[:max_threads])
|
47
|
+
# Not an 'exposed' option, options[:pool_shutdown_grace_time] is used in CI
|
48
|
+
# to shorten @shutdown_grace_time from SHUTDOWN_GRACE_TIME. Parallel CI
|
49
|
+
# makes stubbing constants difficult.
|
50
|
+
@shutdown_grace_time = Float(options[:pool_shutdown_grace_time] || SHUTDOWN_GRACE_TIME)
|
45
51
|
@block = block
|
46
|
-
@
|
52
|
+
@out_of_band = options[:out_of_band]
|
53
|
+
@clean_thread_locals = options[:clean_thread_locals]
|
54
|
+
@reaping_time = options[:reaping_time]
|
55
|
+
@auto_trim_time = options[:auto_trim_time]
|
47
56
|
|
48
57
|
@shutdown = false
|
49
58
|
|
@@ -62,17 +71,14 @@ module Puma
|
|
62
71
|
end
|
63
72
|
end
|
64
73
|
|
65
|
-
@clean_thread_locals = false
|
66
74
|
@force_shutdown = false
|
67
75
|
@shutdown_mutex = Mutex.new
|
68
76
|
end
|
69
77
|
|
70
78
|
attr_reader :spawned, :trim_requested, :waiting
|
71
|
-
attr_accessor :clean_thread_locals
|
72
|
-
attr_accessor :out_of_band_hook # @version 5.0.0
|
73
79
|
|
74
80
|
def self.clean_thread_locals
|
75
|
-
Thread.current.keys.each do |key| # rubocop: disable
|
81
|
+
Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods
|
76
82
|
Thread.current[key] = nil unless key == :__recursive_key__
|
77
83
|
end
|
78
84
|
end
|
@@ -102,15 +108,13 @@ module Puma
|
|
102
108
|
@spawned += 1
|
103
109
|
|
104
110
|
th = Thread.new(@spawned) do |spawned|
|
105
|
-
Puma.set_thread_name '%s
|
111
|
+
Puma.set_thread_name '%s tp %03i' % [@name, spawned]
|
106
112
|
todo = @todo
|
107
113
|
block = @block
|
108
114
|
mutex = @mutex
|
109
115
|
not_empty = @not_empty
|
110
116
|
not_full = @not_full
|
111
117
|
|
112
|
-
extra = @extra.map { |i| i.new }
|
113
|
-
|
114
118
|
while true
|
115
119
|
work = nil
|
116
120
|
|
@@ -144,7 +148,7 @@ module Puma
|
|
144
148
|
end
|
145
149
|
|
146
150
|
begin
|
147
|
-
@out_of_band_pending = true if block.call(work
|
151
|
+
@out_of_band_pending = true if block.call(work)
|
148
152
|
rescue Exception => e
|
149
153
|
STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})"
|
150
154
|
end
|
@@ -160,12 +164,12 @@ module Puma
|
|
160
164
|
|
161
165
|
# @version 5.0.0
|
162
166
|
def trigger_out_of_band_hook
|
163
|
-
return false unless
|
167
|
+
return false unless @out_of_band&.any?
|
164
168
|
|
165
169
|
# we execute on idle hook when all threads are free
|
166
170
|
return false unless @spawned == @waiting
|
167
171
|
|
168
|
-
|
172
|
+
@out_of_band.each(&:call)
|
169
173
|
true
|
170
174
|
rescue Exception => e
|
171
175
|
STDERR.puts "Exception calling out_of_band_hook: #{e.message} (#{e.class})"
|
@@ -319,12 +323,12 @@ module Puma
|
|
319
323
|
end
|
320
324
|
end
|
321
325
|
|
322
|
-
def auto_trim!(timeout
|
326
|
+
def auto_trim!(timeout=@auto_trim_time)
|
323
327
|
@auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
|
324
328
|
@auto_trim.start!
|
325
329
|
end
|
326
330
|
|
327
|
-
def auto_reap!(timeout
|
331
|
+
def auto_reap!(timeout=@reaping_time)
|
328
332
|
@reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
|
329
333
|
@reaper.start!
|
330
334
|
end
|
@@ -344,8 +348,8 @@ module Puma
|
|
344
348
|
|
345
349
|
# Tell all threads in the pool to exit and wait for them to finish.
|
346
350
|
# Wait +timeout+ seconds then raise +ForceShutdown+ in remaining threads.
|
347
|
-
# Next, wait an extra +
|
348
|
-
# Finally, wait
|
351
|
+
# Next, wait an extra +@shutdown_grace_time+ seconds then force-kill remaining
|
352
|
+
# threads. Finally, wait 1 second for remaining threads to exit.
|
349
353
|
#
|
350
354
|
def shutdown(timeout=-1)
|
351
355
|
threads = with_mutex do
|
@@ -354,8 +358,8 @@ module Puma
|
|
354
358
|
@not_empty.broadcast
|
355
359
|
@not_full.broadcast
|
356
360
|
|
357
|
-
@auto_trim
|
358
|
-
@reaper
|
361
|
+
@auto_trim&.stop
|
362
|
+
@reaper&.stop
|
359
363
|
# dup workers so that we join them all safely
|
360
364
|
@workers.dup
|
361
365
|
end
|
@@ -382,7 +386,7 @@ module Puma
|
|
382
386
|
t.raise ForceShutdown if t[:with_force_shutdown]
|
383
387
|
end
|
384
388
|
end
|
385
|
-
join.call(
|
389
|
+
join.call(@shutdown_grace_time)
|
386
390
|
|
387
391
|
# If threads are _still_ running, forcefully kill them and wait to finish.
|
388
392
|
threads.each(&:kill)
|
data/lib/puma/util.rb
CHANGED
@@ -17,29 +17,27 @@ module Puma
|
|
17
17
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
18
18
|
end
|
19
19
|
|
20
|
-
#
|
21
|
-
#
|
20
|
+
# Escapes and unescapes a URI escaped string with
|
21
|
+
# +encoding+. +encoding+ will be the target encoding of the string
|
22
|
+
# returned, and it defaults to UTF-8
|
22
23
|
if defined?(::Encoding)
|
24
|
+
def escape(s, encoding = Encoding::UTF_8)
|
25
|
+
URI.encode_www_form_component(s, encoding)
|
26
|
+
end
|
27
|
+
|
23
28
|
def unescape(s, encoding = Encoding::UTF_8)
|
24
29
|
URI.decode_www_form_component(s, encoding)
|
25
30
|
end
|
26
31
|
else
|
27
|
-
def
|
28
|
-
URI.
|
32
|
+
def escape(s, encoding = nil)
|
33
|
+
URI.encode_www_form_component(s, encoding)
|
29
34
|
end
|
30
|
-
end
|
31
|
-
module_function :unescape
|
32
35
|
|
33
|
-
|
34
|
-
|
35
|
-
events.log "! Promoting existing objects to old generation..."
|
36
|
-
4.times { GC.start(full_mark: false) }
|
37
|
-
if GC.respond_to?(:compact)
|
38
|
-
events.log "! Compacting..."
|
39
|
-
GC.compact
|
36
|
+
def unescape(s, encoding = nil)
|
37
|
+
URI.decode_www_form_component(s, encoding)
|
40
38
|
end
|
41
|
-
events.log "! Friendly fork preparation complete."
|
42
39
|
end
|
40
|
+
module_function :unescape, :escape
|
43
41
|
|
44
42
|
DEFAULT_SEP = /[&;] */n
|
45
43
|
|
data/lib/puma.rb
CHANGED
@@ -3,30 +3,33 @@
|
|
3
3
|
# Standard libraries
|
4
4
|
require 'socket'
|
5
5
|
require 'tempfile'
|
6
|
-
require 'time'
|
7
|
-
require 'etc'
|
8
6
|
require 'uri'
|
9
7
|
require 'stringio'
|
10
8
|
|
11
9
|
require 'thread'
|
12
10
|
|
11
|
+
# use require, see https://github.com/puma/puma/pull/2381
|
13
12
|
require 'puma/puma_http11'
|
14
|
-
|
15
|
-
|
13
|
+
|
14
|
+
require_relative 'puma/detect'
|
15
|
+
require_relative 'puma/json_serialization'
|
16
16
|
|
17
17
|
module Puma
|
18
|
-
|
19
|
-
|
20
|
-
autoload :
|
18
|
+
# when Puma is loaded via `Puma::CLI`, all files are loaded via
|
19
|
+
# `require_relative`. The below are for non-standard loading
|
20
|
+
autoload :Const, "#{__dir__}/puma/const"
|
21
|
+
autoload :Server, "#{__dir__}/puma/server"
|
22
|
+
autoload :Launcher, "#{__dir__}/puma/launcher"
|
23
|
+
autoload :LogWriter, "#{__dir__}/puma/log_writer"
|
21
24
|
|
22
25
|
# at present, MiniSSL::Engine is only defined in extension code (puma_http11),
|
23
26
|
# not in minissl.rb
|
24
27
|
HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
|
25
28
|
|
26
|
-
HAS_UNIX_SOCKET = Object.const_defined?
|
29
|
+
HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS
|
27
30
|
|
28
31
|
if HAS_SSL
|
29
|
-
|
32
|
+
require_relative 'puma/minissl'
|
30
33
|
else
|
31
34
|
module MiniSSL
|
32
35
|
# this class is defined so that it exists when Puma is compiled
|
@@ -69,9 +72,7 @@ module Puma
|
|
69
72
|
@get_stats.stats
|
70
73
|
end
|
71
74
|
|
72
|
-
# Thread name is new in Ruby 2.3
|
73
75
|
def self.set_thread_name(name)
|
74
|
-
return unless Thread.current.respond_to?(:name=)
|
75
76
|
Thread.current.name = "puma #{name}"
|
76
77
|
end
|
77
78
|
end
|
data/lib/rack/handler/puma.rb
CHANGED
@@ -1,114 +1,141 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
module
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
(options.keys - user_supplied_options).each do |k|
|
28
|
-
default_options[k] = options.delete(k)
|
29
|
-
end
|
3
|
+
# This module is used as an 'include' file in code at bottom of file
|
4
|
+
module Puma
|
5
|
+
module RackHandler
|
6
|
+
DEFAULT_OPTIONS = {
|
7
|
+
:Verbose => false,
|
8
|
+
:Silent => false
|
9
|
+
}
|
10
|
+
|
11
|
+
def config(app, options = {})
|
12
|
+
require_relative '../../puma'
|
13
|
+
require_relative '../../puma/configuration'
|
14
|
+
require_relative '../../puma/log_writer'
|
15
|
+
require_relative '../../puma/launcher'
|
16
|
+
|
17
|
+
default_options = DEFAULT_OPTIONS.dup
|
18
|
+
|
19
|
+
# Libraries pass in values such as :Port and there is no way to determine
|
20
|
+
# if it is a default provided by the library or a special value provided
|
21
|
+
# by the user. A special key `user_supplied_options` can be passed. This
|
22
|
+
# contains an array of all explicitly defined user options. We then
|
23
|
+
# know that all other values are defaults
|
24
|
+
if user_supplied_options = options.delete(:user_supplied_options)
|
25
|
+
(options.keys - user_supplied_options).each do |k|
|
26
|
+
default_options[k] = options.delete(k)
|
30
27
|
end
|
28
|
+
end
|
31
29
|
|
32
|
-
|
33
|
-
if options.delete(:Verbose)
|
34
|
-
require 'rack/common_logger'
|
35
|
-
app = Rack::CommonLogger.new(app, STDOUT)
|
36
|
-
end
|
30
|
+
@events = options[:events] || ::Puma::Events.new
|
37
31
|
|
38
|
-
|
39
|
-
|
32
|
+
conf = ::Puma::Configuration.new(options, default_options.merge({events: @events})) do |user_config, file_config, default_config|
|
33
|
+
if options.delete(:Verbose)
|
34
|
+
begin
|
35
|
+
require 'rack/commonlogger' # Rack 1.x
|
36
|
+
rescue LoadError
|
37
|
+
require 'rack/common_logger' # Rack 2 and later
|
40
38
|
end
|
39
|
+
app = ::Rack::CommonLogger.new(app, STDOUT)
|
40
|
+
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
42
|
+
if options[:environment]
|
43
|
+
user_config.environment options[:environment]
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
46
|
+
if options[:Threads]
|
47
|
+
min, max = options.delete(:Threads).split(':', 2)
|
48
|
+
user_config.threads min, max
|
49
|
+
end
|
52
50
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
self.set_host_port_to_config(
|
51
|
+
if options[:Host] || options[:Port]
|
52
|
+
host = options[:Host] || default_options[:Host]
|
53
|
+
port = options[:Port] || default_options[:Port]
|
54
|
+
self.set_host_port_to_config(host, port, user_config)
|
55
|
+
end
|
57
56
|
|
58
|
-
|
57
|
+
if default_options[:Host]
|
58
|
+
file_config.set_default_host(default_options[:Host])
|
59
59
|
end
|
60
|
-
|
60
|
+
self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
|
61
|
+
|
62
|
+
user_config.app app
|
61
63
|
end
|
64
|
+
conf
|
65
|
+
end
|
62
66
|
|
63
|
-
|
64
|
-
|
67
|
+
def run(app, **options)
|
68
|
+
conf = self.config(app, options)
|
65
69
|
|
66
|
-
|
70
|
+
log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
|
67
71
|
|
68
|
-
|
72
|
+
launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer, events: @events)
|
69
73
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
74
|
+
yield launcher if block_given?
|
75
|
+
begin
|
76
|
+
launcher.run
|
77
|
+
rescue Interrupt
|
78
|
+
puts "* Gracefully stopping, waiting for requests to finish"
|
79
|
+
launcher.stop
|
80
|
+
puts "* Goodbye!"
|
78
81
|
end
|
82
|
+
end
|
79
83
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
84
|
+
def valid_options
|
85
|
+
{
|
86
|
+
"Host=HOST" => "Hostname to listen on (default: localhost)",
|
87
|
+
"Port=PORT" => "Port to listen on (default: 8080)",
|
88
|
+
"Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
|
89
|
+
"Verbose" => "Don't report each request (default: false)"
|
90
|
+
}
|
91
|
+
end
|
88
92
|
|
89
|
-
|
90
|
-
|
93
|
+
def set_host_port_to_config(host, port, config)
|
94
|
+
config.clear_binds! if host || port
|
91
95
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
if host && (host[0,1] == '.' || host[0,1] == '/')
|
97
|
+
config.bind "unix://#{host}"
|
98
|
+
elsif host && host =~ /^ssl:\/\//
|
99
|
+
uri = URI.parse(host)
|
100
|
+
uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
|
101
|
+
config.bind uri.to_s
|
102
|
+
else
|
99
103
|
|
100
|
-
|
101
|
-
|
102
|
-
|
104
|
+
if host
|
105
|
+
port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
|
106
|
+
end
|
103
107
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
108
|
+
if port
|
109
|
+
host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
|
110
|
+
config.port port, host
|
108
111
|
end
|
109
112
|
end
|
110
113
|
end
|
114
|
+
end
|
115
|
+
end
|
111
116
|
|
112
|
-
|
117
|
+
# rackup was removed in Rack 3, it is now a separate gem
|
118
|
+
if Object.const_defined? :Rackup
|
119
|
+
module Rackup
|
120
|
+
module Handler
|
121
|
+
module Puma
|
122
|
+
class << self
|
123
|
+
include ::Puma::RackHandler
|
124
|
+
end
|
125
|
+
end
|
126
|
+
register :puma, Puma
|
127
|
+
end
|
128
|
+
end
|
129
|
+
else
|
130
|
+
do_register = Object.const_defined?(:Rack) && Rack.release < '3'
|
131
|
+
module Rack
|
132
|
+
module Handler
|
133
|
+
module Puma
|
134
|
+
class << self
|
135
|
+
include ::Puma::RackHandler
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
113
139
|
end
|
140
|
+
::Rack::Handler.register(:puma, ::Rack::Handler::Puma) if do_register
|
114
141
|
end
|
data/tools/Dockerfile
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 1980-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -62,6 +62,8 @@ files:
|
|
62
62
|
- docs/signals.md
|
63
63
|
- docs/stats.md
|
64
64
|
- docs/systemd.md
|
65
|
+
- docs/testing_benchmarks_local_files.md
|
66
|
+
- docs/testing_test_rackup_ci_files.md
|
65
67
|
- ext/puma_http11/PumaHttp11Service.java
|
66
68
|
- ext/puma_http11/ext_help.h
|
67
69
|
- ext/puma_http11/extconf.rb
|
@@ -96,22 +98,24 @@ files:
|
|
96
98
|
- lib/puma/jruby_restart.rb
|
97
99
|
- lib/puma/json_serialization.rb
|
98
100
|
- lib/puma/launcher.rb
|
101
|
+
- lib/puma/launcher/bundle_pruner.rb
|
102
|
+
- lib/puma/log_writer.rb
|
99
103
|
- lib/puma/minissl.rb
|
100
104
|
- lib/puma/minissl/context_builder.rb
|
101
105
|
- lib/puma/null_io.rb
|
102
106
|
- lib/puma/plugin.rb
|
107
|
+
- lib/puma/plugin/systemd.rb
|
103
108
|
- lib/puma/plugin/tmp_restart.rb
|
104
|
-
- lib/puma/queue_close.rb
|
105
109
|
- lib/puma/rack/builder.rb
|
106
110
|
- lib/puma/rack/urlmap.rb
|
107
111
|
- lib/puma/rack_default.rb
|
108
112
|
- lib/puma/reactor.rb
|
109
113
|
- lib/puma/request.rb
|
110
114
|
- lib/puma/runner.rb
|
115
|
+
- lib/puma/sd_notify.rb
|
111
116
|
- lib/puma/server.rb
|
112
117
|
- lib/puma/single.rb
|
113
118
|
- lib/puma/state_file.rb
|
114
|
-
- lib/puma/systemd.rb
|
115
119
|
- lib/puma/thread_pool.rb
|
116
120
|
- lib/puma/util.rb
|
117
121
|
- lib/rack/handler/puma.rb
|
@@ -125,6 +129,7 @@ metadata:
|
|
125
129
|
changelog_uri: https://github.com/puma/puma/blob/master/History.md
|
126
130
|
homepage_uri: https://puma.io
|
127
131
|
source_code_uri: https://github.com/puma/puma
|
132
|
+
rubygems_mfa_required: 'true'
|
128
133
|
post_install_message:
|
129
134
|
rdoc_options: []
|
130
135
|
require_paths:
|
@@ -133,14 +138,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
138
|
requirements:
|
134
139
|
- - ">="
|
135
140
|
- !ruby/object:Gem::Version
|
136
|
-
version: '2.
|
141
|
+
version: '2.4'
|
137
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
143
|
requirements:
|
139
144
|
- - ">="
|
140
145
|
- !ruby/object:Gem::Version
|
141
146
|
version: '0'
|
142
147
|
requirements: []
|
143
|
-
rubygems_version: 3.
|
148
|
+
rubygems_version: 3.4.12
|
144
149
|
signing_key:
|
145
150
|
specification_version: 4
|
146
151
|
summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
|