puma 5.3.2 → 6.0.0
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.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +284 -11
- data/LICENSE +0 -0
- data/README.md +61 -16
- data/bin/puma-wild +1 -1
- data/docs/architecture.md +49 -16
- data/docs/compile_options.md +38 -2
- data/docs/deployment.md +53 -67
- data/docs/fork_worker.md +1 -3
- 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/jungle/README.md +0 -0
- data/docs/jungle/rc.d/README.md +0 -0
- data/docs/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +0 -0
- data/docs/nginx.md +0 -0
- data/docs/plugins.md +15 -15
- data/docs/rails_dev_mode.md +2 -3
- data/docs/restart.md +6 -6
- data/docs/signals.md +11 -10
- data/docs/stats.md +8 -8
- data/docs/systemd.md +64 -67
- data/docs/testing_benchmarks_local_files.md +150 -0
- data/docs/testing_test_rackup_ci_files.md +36 -0
- data/ext/puma_http11/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/ext_help.h +0 -0
- data/ext/puma_http11/extconf.rb +44 -13
- data/ext/puma_http11/http11_parser.c +24 -11
- 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 +3 -3
- data/ext/puma_http11/mini_ssl.c +122 -23
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +50 -48
- 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 +9 -6
- data/lib/puma/binder.rb +81 -42
- data/lib/puma/cli.rb +23 -19
- data/lib/puma/client.rb +124 -30
- data/lib/puma/cluster/worker.rb +21 -29
- data/lib/puma/cluster/worker_handle.rb +8 -1
- data/lib/puma/cluster.rb +57 -48
- data/lib/puma/commonlogger.rb +0 -0
- data/lib/puma/configuration.rb +74 -55
- data/lib/puma/const.rb +21 -24
- data/lib/puma/control_cli.rb +22 -19
- data/lib/puma/detect.rb +10 -2
- data/lib/puma/dsl.rb +196 -57
- data/lib/puma/error_logger.rb +17 -9
- data/lib/puma/events.rb +6 -126
- data/lib/puma/io_buffer.rb +29 -4
- data/lib/puma/jruby_restart.rb +2 -1
- data/lib/puma/{json.rb → json_serialization.rb} +1 -1
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +108 -154
- data/lib/puma/log_writer.rb +137 -0
- data/lib/puma/minissl/context_builder.rb +29 -16
- data/lib/puma/minissl.rb +115 -38
- data/lib/puma/null_io.rb +5 -0
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/plugin.rb +2 -2
- data/lib/puma/rack/builder.rb +5 -5
- data/lib/puma/rack/urlmap.rb +0 -0
- data/lib/puma/rack_default.rb +1 -1
- data/lib/puma/reactor.rb +3 -3
- data/lib/puma/request.rb +293 -153
- data/lib/puma/runner.rb +63 -28
- data/lib/puma/server.rb +83 -88
- data/lib/puma/single.rb +10 -10
- data/lib/puma/state_file.rb +39 -7
- data/lib/puma/systemd.rb +3 -2
- data/lib/puma/thread_pool.rb +22 -17
- data/lib/puma/util.rb +20 -15
- data/lib/puma.rb +12 -9
- data/lib/rack/handler/puma.rb +9 -9
- data/tools/Dockerfile +1 -1
- data/tools/trickletest.rb +0 -0
- metadata +13 -9
- data/lib/puma/queue_close.rb +0 -26
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(
|
34
|
+
def initialize(name, options = {}, &block)
|
33
35
|
@not_empty = ConditionVariable.new
|
34
36
|
@not_full = ConditionVariable.new
|
35
37
|
@mutex = Mutex.new
|
@@ -39,10 +41,15 @@ module Puma
|
|
39
41
|
@spawned = 0
|
40
42
|
@waiting = 0
|
41
43
|
|
42
|
-
@
|
43
|
-
@
|
44
|
+
@name = name
|
45
|
+
@min = Integer(options[:min_threads])
|
46
|
+
@max = Integer(options[:max_threads])
|
44
47
|
@block = block
|
45
|
-
@extra =
|
48
|
+
@extra = [::Puma::IOBuffer]
|
49
|
+
@out_of_band = options[:out_of_band]
|
50
|
+
@clean_thread_locals = options[:clean_thread_locals]
|
51
|
+
@reaping_time = options[:reaping_time]
|
52
|
+
@auto_trim_time = options[:auto_trim_time]
|
46
53
|
|
47
54
|
@shutdown = false
|
48
55
|
|
@@ -61,17 +68,14 @@ module Puma
|
|
61
68
|
end
|
62
69
|
end
|
63
70
|
|
64
|
-
@clean_thread_locals = false
|
65
71
|
@force_shutdown = false
|
66
72
|
@shutdown_mutex = Mutex.new
|
67
73
|
end
|
68
74
|
|
69
75
|
attr_reader :spawned, :trim_requested, :waiting
|
70
|
-
attr_accessor :clean_thread_locals
|
71
|
-
attr_accessor :out_of_band_hook # @version 5.0.0
|
72
76
|
|
73
77
|
def self.clean_thread_locals
|
74
|
-
Thread.current.keys.each do |key| # rubocop: disable
|
78
|
+
Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods
|
75
79
|
Thread.current[key] = nil unless key == :__recursive_key__
|
76
80
|
end
|
77
81
|
end
|
@@ -101,7 +105,7 @@ module Puma
|
|
101
105
|
@spawned += 1
|
102
106
|
|
103
107
|
th = Thread.new(@spawned) do |spawned|
|
104
|
-
Puma.set_thread_name '
|
108
|
+
Puma.set_thread_name '%s tp %03i' % [@name, spawned]
|
105
109
|
todo = @todo
|
106
110
|
block = @block
|
107
111
|
mutex = @mutex
|
@@ -119,6 +123,7 @@ module Puma
|
|
119
123
|
@trim_requested -= 1
|
120
124
|
@spawned -= 1
|
121
125
|
@workers.delete th
|
126
|
+
not_full.signal
|
122
127
|
Thread.exit
|
123
128
|
end
|
124
129
|
|
@@ -158,12 +163,12 @@ module Puma
|
|
158
163
|
|
159
164
|
# @version 5.0.0
|
160
165
|
def trigger_out_of_band_hook
|
161
|
-
return false unless
|
166
|
+
return false unless @out_of_band&.any?
|
162
167
|
|
163
168
|
# we execute on idle hook when all threads are free
|
164
169
|
return false unless @spawned == @waiting
|
165
170
|
|
166
|
-
|
171
|
+
@out_of_band.each(&:call)
|
167
172
|
true
|
168
173
|
rescue Exception => e
|
169
174
|
STDERR.puts "Exception calling out_of_band_hook: #{e.message} (#{e.class})"
|
@@ -317,13 +322,13 @@ module Puma
|
|
317
322
|
end
|
318
323
|
end
|
319
324
|
|
320
|
-
def auto_trim!(timeout
|
321
|
-
@auto_trim = Automaton.new(self, timeout, "threadpool trimmer", :trim)
|
325
|
+
def auto_trim!(timeout=@auto_trim_time)
|
326
|
+
@auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
|
322
327
|
@auto_trim.start!
|
323
328
|
end
|
324
329
|
|
325
|
-
def auto_reap!(timeout
|
326
|
-
@reaper = Automaton.new(self, timeout, "threadpool reaper", :reap)
|
330
|
+
def auto_reap!(timeout=@reaping_time)
|
331
|
+
@reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
|
327
332
|
@reaper.start!
|
328
333
|
end
|
329
334
|
|
@@ -352,8 +357,8 @@ module Puma
|
|
352
357
|
@not_empty.broadcast
|
353
358
|
@not_full.broadcast
|
354
359
|
|
355
|
-
@auto_trim
|
356
|
-
@reaper
|
360
|
+
@auto_trim&.stop
|
361
|
+
@reaper&.stop
|
357
362
|
# dup workers so that we join them all safely
|
358
363
|
@workers.dup
|
359
364
|
end
|
data/lib/puma/util.rb
CHANGED
@@ -10,29 +10,34 @@ module Puma
|
|
10
10
|
IO.pipe
|
11
11
|
end
|
12
12
|
|
13
|
-
#
|
14
|
-
#
|
13
|
+
# An instance method on Thread has been provided to address https://bugs.ruby-lang.org/issues/13632,
|
14
|
+
# which currently effects some older versions of Ruby: 2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1
|
15
|
+
# Additional context: https://github.com/puma/puma/pull/1345
|
16
|
+
def purge_interrupt_queue
|
17
|
+
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
18
|
+
end
|
19
|
+
|
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
|
15
23
|
if defined?(::Encoding)
|
24
|
+
def escape(s, encoding = Encoding::UTF_8)
|
25
|
+
URI.encode_www_form_component(s, encoding)
|
26
|
+
end
|
27
|
+
|
16
28
|
def unescape(s, encoding = Encoding::UTF_8)
|
17
29
|
URI.decode_www_form_component(s, encoding)
|
18
30
|
end
|
19
31
|
else
|
20
|
-
def
|
21
|
-
URI.
|
32
|
+
def escape(s, encoding = nil)
|
33
|
+
URI.encode_www_form_component(s, encoding)
|
22
34
|
end
|
23
|
-
end
|
24
|
-
module_function :unescape
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
events.log "! Promoting existing objects to old generation..."
|
29
|
-
4.times { GC.start(full_mark: false) }
|
30
|
-
if GC.respond_to?(:compact)
|
31
|
-
events.log "! Compacting..."
|
32
|
-
GC.compact
|
36
|
+
def unescape(s, encoding = nil)
|
37
|
+
URI.decode_www_form_component(s, encoding)
|
33
38
|
end
|
34
|
-
events.log "! Friendly fork preparation complete."
|
35
39
|
end
|
40
|
+
module_function :unescape, :escape
|
36
41
|
|
37
42
|
DEFAULT_SEP = /[&;] */n
|
38
43
|
|
@@ -61,7 +66,7 @@ module Puma
|
|
61
66
|
end
|
62
67
|
end
|
63
68
|
|
64
|
-
|
69
|
+
params
|
65
70
|
end
|
66
71
|
|
67
72
|
# A case-insensitive Hash that preserves the original case of a
|
data/lib/puma.rb
CHANGED
@@ -10,14 +10,19 @@ require 'stringio'
|
|
10
10
|
|
11
11
|
require 'thread'
|
12
12
|
|
13
|
+
# use require, see https://github.com/puma/puma/pull/2381
|
13
14
|
require 'puma/puma_http11'
|
14
|
-
|
15
|
-
|
15
|
+
|
16
|
+
require_relative 'puma/detect'
|
17
|
+
require_relative 'puma/json_serialization'
|
16
18
|
|
17
19
|
module Puma
|
18
|
-
|
19
|
-
|
20
|
-
autoload :
|
20
|
+
# when Puma is loaded via `Puma::CLI`, all files are loaded via
|
21
|
+
# `require_relative`. The below are for non-standard loading
|
22
|
+
autoload :Const, "#{__dir__}/puma/const"
|
23
|
+
autoload :Server, "#{__dir__}/puma/server"
|
24
|
+
autoload :Launcher, "#{__dir__}/puma/launcher"
|
25
|
+
autoload :LogWriter, "#{__dir__}/puma/log_writer"
|
21
26
|
|
22
27
|
# at present, MiniSSL::Engine is only defined in extension code (puma_http11),
|
23
28
|
# not in minissl.rb
|
@@ -26,7 +31,7 @@ module Puma
|
|
26
31
|
HAS_UNIX_SOCKET = Object.const_defined? :UNIXSocket
|
27
32
|
|
28
33
|
if HAS_SSL
|
29
|
-
|
34
|
+
require_relative 'puma/minissl'
|
30
35
|
else
|
31
36
|
module MiniSSL
|
32
37
|
# this class is defined so that it exists when Puma is compiled
|
@@ -60,7 +65,7 @@ module Puma
|
|
60
65
|
|
61
66
|
# @!attribute [rw] stats_object
|
62
67
|
def self.stats
|
63
|
-
Puma::
|
68
|
+
Puma::JSONSerialization.generate @get_stats.stats
|
64
69
|
end
|
65
70
|
|
66
71
|
# @!attribute [r] stats_hash
|
@@ -69,9 +74,7 @@ module Puma
|
|
69
74
|
@get_stats.stats
|
70
75
|
end
|
71
76
|
|
72
|
-
# Thread name is new in Ruby 2.3
|
73
77
|
def self.set_thread_name(name)
|
74
|
-
return unless Thread.current.respond_to?(:name=)
|
75
78
|
Thread.current.name = "puma #{name}"
|
76
79
|
end
|
77
80
|
end
|
data/lib/rack/handler/puma.rb
CHANGED
@@ -11,10 +11,10 @@ module Rack
|
|
11
11
|
}
|
12
12
|
|
13
13
|
def self.config(app, options = {})
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
require_relative '../../puma'
|
15
|
+
require_relative '../../puma/configuration'
|
16
|
+
require_relative '../../puma/log_writer'
|
17
|
+
require_relative '../../puma/launcher'
|
18
18
|
|
19
19
|
default_options = DEFAULT_OPTIONS.dup
|
20
20
|
|
@@ -63,9 +63,9 @@ module Rack
|
|
63
63
|
def self.run(app, **options)
|
64
64
|
conf = self.config(app, options)
|
65
65
|
|
66
|
-
|
66
|
+
log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
|
67
67
|
|
68
|
-
launcher = ::Puma::Launcher.new(conf, :
|
68
|
+
launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer)
|
69
69
|
|
70
70
|
yield launcher if block_given?
|
71
71
|
begin
|
@@ -93,16 +93,16 @@ module Rack
|
|
93
93
|
config.bind "unix://#{host}"
|
94
94
|
elsif host && host =~ /^ssl:\/\//
|
95
95
|
uri = URI.parse(host)
|
96
|
-
uri.port ||= port || ::Puma::Configuration::
|
96
|
+
uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
|
97
97
|
config.bind uri.to_s
|
98
98
|
else
|
99
99
|
|
100
100
|
if host
|
101
|
-
port ||= ::Puma::Configuration::
|
101
|
+
port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
|
102
102
|
end
|
103
103
|
|
104
104
|
if port
|
105
|
-
host ||= ::Puma::Configuration::
|
105
|
+
host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
|
106
106
|
config.port port, host
|
107
107
|
end
|
108
108
|
end
|
data/tools/Dockerfile
CHANGED
data/tools/trickletest.rb
CHANGED
File without changes
|
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.0.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
|
@@ -24,9 +24,9 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
|
-
description: Puma is a simple, fast, threaded, and highly
|
27
|
+
description: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server
|
28
28
|
for Ruby/Rack applications. Puma is intended for use in both development and production
|
29
|
-
environments. It's great for highly
|
29
|
+
environments. It's great for highly parallel Ruby implementations such as Rubinius
|
30
30
|
and JRuby as well as as providing process worker support to support CRuby well.
|
31
31
|
email:
|
32
32
|
- evan@phx.io
|
@@ -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
|
@@ -94,14 +96,15 @@ files:
|
|
94
96
|
- lib/puma/events.rb
|
95
97
|
- lib/puma/io_buffer.rb
|
96
98
|
- lib/puma/jruby_restart.rb
|
97
|
-
- lib/puma/
|
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
|
103
107
|
- lib/puma/plugin/tmp_restart.rb
|
104
|
-
- lib/puma/queue_close.rb
|
105
108
|
- lib/puma/rack/builder.rb
|
106
109
|
- lib/puma/rack/urlmap.rb
|
107
110
|
- lib/puma/rack_default.rb
|
@@ -125,6 +128,7 @@ metadata:
|
|
125
128
|
changelog_uri: https://github.com/puma/puma/blob/master/History.md
|
126
129
|
homepage_uri: https://puma.io
|
127
130
|
source_code_uri: https://github.com/puma/puma
|
131
|
+
rubygems_mfa_required: 'true'
|
128
132
|
post_install_message:
|
129
133
|
rdoc_options: []
|
130
134
|
require_paths:
|
@@ -133,16 +137,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
137
|
requirements:
|
134
138
|
- - ">="
|
135
139
|
- !ruby/object:Gem::Version
|
136
|
-
version: '2.
|
140
|
+
version: '2.4'
|
137
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
142
|
requirements:
|
139
143
|
- - ">="
|
140
144
|
- !ruby/object:Gem::Version
|
141
145
|
version: '0'
|
142
146
|
requirements: []
|
143
|
-
rubygems_version: 3.2.
|
147
|
+
rubygems_version: 3.2.26
|
144
148
|
signing_key:
|
145
149
|
specification_version: 4
|
146
|
-
summary: Puma is a simple, fast, threaded, and highly
|
150
|
+
summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
|
147
151
|
Ruby/Rack applications
|
148
152
|
test_files: []
|
data/lib/puma/queue_close.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
class ClosedQueueError < StandardError; end
|
2
|
-
module Puma
|
3
|
-
|
4
|
-
# Queue#close was added in Ruby 2.3.
|
5
|
-
# Add a simple implementation for earlier Ruby versions.
|
6
|
-
#
|
7
|
-
module QueueClose
|
8
|
-
def close
|
9
|
-
num_waiting.times {push nil}
|
10
|
-
@closed = true
|
11
|
-
end
|
12
|
-
def closed?
|
13
|
-
@closed ||= false
|
14
|
-
end
|
15
|
-
def push(object)
|
16
|
-
raise ClosedQueueError if closed?
|
17
|
-
super
|
18
|
-
end
|
19
|
-
alias << push
|
20
|
-
def pop(non_block=false)
|
21
|
-
return nil if !non_block && closed? && empty?
|
22
|
-
super
|
23
|
-
end
|
24
|
-
end
|
25
|
-
::Queue.prepend QueueClose
|
26
|
-
end
|