puma 5.0.4 → 5.6.4
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 +322 -48
- data/LICENSE +0 -0
- data/README.md +95 -24
- data/bin/puma-wild +0 -0
- data/docs/architecture.md +57 -20
- data/docs/compile_options.md +21 -0
- data/docs/deployment.md +53 -67
- data/docs/fork_worker.md +2 -0
- 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 +1 -1
- data/docs/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +66 -0
- data/docs/nginx.md +0 -0
- data/docs/plugins.md +15 -15
- data/docs/rails_dev_mode.md +28 -0
- data/docs/restart.md +7 -7
- data/docs/signals.md +11 -10
- data/docs/stats.md +142 -0
- data/docs/systemd.md +85 -66
- data/ext/puma_http11/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/ext_help.h +0 -0
- data/ext/puma_http11/extconf.rb +42 -6
- data/ext/puma_http11/http11_parser.c +68 -57
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +1 -1
- data/ext/puma_http11/http11_parser.rl +1 -1
- data/ext/puma_http11/http11_parser_common.rl +1 -1
- data/ext/puma_http11/mini_ssl.c +226 -88
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +51 -51
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +28 -43
- data/ext/puma_http11/puma_http11.c +9 -3
- data/lib/puma/app/status.rb +4 -7
- data/lib/puma/binder.rb +138 -49
- data/lib/puma/cli.rb +18 -4
- data/lib/puma/client.rb +113 -31
- data/lib/puma/cluster/worker.rb +22 -19
- data/lib/puma/cluster/worker_handle.rb +13 -2
- data/lib/puma/cluster.rb +75 -33
- data/lib/puma/commonlogger.rb +0 -0
- data/lib/puma/configuration.rb +21 -2
- data/lib/puma/const.rb +17 -8
- data/lib/puma/control_cli.rb +76 -71
- data/lib/puma/detect.rb +19 -9
- data/lib/puma/dsl.rb +225 -31
- data/lib/puma/error_logger.rb +12 -5
- data/lib/puma/events.rb +18 -3
- data/lib/puma/io_buffer.rb +0 -0
- data/lib/puma/jruby_restart.rb +0 -0
- data/lib/puma/json_serialization.rb +96 -0
- data/lib/puma/launcher.rb +56 -7
- data/lib/puma/minissl/context_builder.rb +14 -6
- data/lib/puma/minissl.rb +72 -40
- data/lib/puma/null_io.rb +12 -0
- data/lib/puma/plugin/tmp_restart.rb +0 -0
- data/lib/puma/plugin.rb +2 -2
- data/lib/puma/queue_close.rb +7 -7
- data/lib/puma/rack/builder.rb +1 -1
- data/lib/puma/rack/urlmap.rb +0 -0
- data/lib/puma/rack_default.rb +0 -0
- data/lib/puma/reactor.rb +19 -12
- data/lib/puma/request.rb +55 -21
- data/lib/puma/runner.rb +39 -13
- data/lib/puma/server.rb +78 -142
- data/lib/puma/single.rb +0 -0
- data/lib/puma/state_file.rb +45 -9
- data/lib/puma/systemd.rb +46 -0
- data/lib/puma/thread_pool.rb +11 -8
- data/lib/puma/util.rb +8 -1
- data/lib/puma.rb +36 -10
- data/lib/rack/handler/puma.rb +1 -0
- data/tools/Dockerfile +1 -1
- data/tools/trickletest.rb +0 -0
- metadata +15 -9
data/lib/puma/state_file.rb
CHANGED
@@ -1,27 +1,63 @@
|
|
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
|
+
|
18
|
+
# @deprecated 6.0.0
|
19
|
+
FIELDS = ALLOWED_FIELDS
|
20
|
+
|
7
21
|
def initialize
|
8
22
|
@options = {}
|
9
23
|
end
|
10
24
|
|
11
25
|
def save(path, permission = nil)
|
12
|
-
|
13
|
-
|
14
|
-
|
26
|
+
contents = "---\n".dup
|
27
|
+
@options.each do |k,v|
|
28
|
+
next unless ALLOWED_FIELDS.include? k
|
29
|
+
case v
|
30
|
+
when Numeric
|
31
|
+
contents << "#{k}: #{v}\n"
|
32
|
+
when String
|
33
|
+
next if v.strip.empty?
|
34
|
+
contents << (k == 'running_from' || v.to_s.include?(' ') ?
|
35
|
+
"#{k}: \"#{v}\"\n" : "#{k}: #{v}\n")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
if permission
|
39
|
+
File.write path, contents, mode: 'wb:UTF-8'
|
40
|
+
else
|
41
|
+
File.write path, contents, mode: 'wb:UTF-8', perm: permission
|
15
42
|
end
|
16
43
|
end
|
17
44
|
|
18
45
|
def load(path)
|
19
|
-
|
46
|
+
File.read(path).lines.each do |line|
|
47
|
+
next if line.start_with? '#'
|
48
|
+
k,v = line.split ':', 2
|
49
|
+
next unless v && ALLOWED_FIELDS.include?(k)
|
50
|
+
v = v.strip
|
51
|
+
@options[k] =
|
52
|
+
case v
|
53
|
+
when /\A\d+\z/ then v.to_i
|
54
|
+
when /\A\d+\.\d+\z/ then v.to_f
|
55
|
+
else v.gsub(/\A"|"\z/, '')
|
56
|
+
end
|
57
|
+
end
|
20
58
|
end
|
21
59
|
|
22
|
-
|
23
|
-
|
24
|
-
FIELDS.each do |f|
|
60
|
+
ALLOWED_FIELDS.each do |f|
|
25
61
|
define_method f do
|
26
62
|
@options[f]
|
27
63
|
end
|
data/lib/puma/systemd.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sd_notify'
|
4
|
+
|
5
|
+
module Puma
|
6
|
+
class Systemd
|
7
|
+
def initialize(events)
|
8
|
+
@events = events
|
9
|
+
end
|
10
|
+
|
11
|
+
def hook_events
|
12
|
+
@events.on_booted { SdNotify.ready }
|
13
|
+
@events.on_stopped { SdNotify.stopping }
|
14
|
+
@events.on_restart { SdNotify.reloading }
|
15
|
+
end
|
16
|
+
|
17
|
+
def start_watchdog
|
18
|
+
return unless SdNotify.watchdog?
|
19
|
+
|
20
|
+
ping_f = watchdog_sleep_time
|
21
|
+
|
22
|
+
log "Pinging systemd watchdog every #{ping_f.round(1)} sec"
|
23
|
+
Thread.new do
|
24
|
+
loop do
|
25
|
+
sleep ping_f
|
26
|
+
SdNotify.watchdog
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def watchdog_sleep_time
|
34
|
+
usec = Integer(ENV["WATCHDOG_USEC"])
|
35
|
+
|
36
|
+
sec_f = usec / 1_000_000.0
|
37
|
+
# "It is recommended that a daemon sends a keep-alive notification message
|
38
|
+
# to the service manager every half of the time returned here."
|
39
|
+
sec_f / 2
|
40
|
+
end
|
41
|
+
|
42
|
+
def log(str)
|
43
|
+
@events.log str
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/puma/thread_pool.rb
CHANGED
@@ -13,7 +13,7 @@ module Puma
|
|
13
13
|
# a thread pool via the `Puma::ThreadPool#<<` operator where it is stored in a `@todo` array.
|
14
14
|
#
|
15
15
|
# Each thread in the pool has an internal loop where it pulls a request from the `@todo` array
|
16
|
-
# and
|
16
|
+
# and processes it.
|
17
17
|
class ThreadPool
|
18
18
|
class ForceShutdown < RuntimeError
|
19
19
|
end
|
@@ -29,7 +29,7 @@ module Puma
|
|
29
29
|
# The block passed is the work that will be performed in each
|
30
30
|
# thread.
|
31
31
|
#
|
32
|
-
def initialize(min, max, *extra, &block)
|
32
|
+
def initialize(name, min, max, *extra, &block)
|
33
33
|
@not_empty = ConditionVariable.new
|
34
34
|
@not_full = ConditionVariable.new
|
35
35
|
@mutex = Mutex.new
|
@@ -39,6 +39,7 @@ module Puma
|
|
39
39
|
@spawned = 0
|
40
40
|
@waiting = 0
|
41
41
|
|
42
|
+
@name = name
|
42
43
|
@min = Integer(min)
|
43
44
|
@max = Integer(max)
|
44
45
|
@block = block
|
@@ -71,7 +72,7 @@ module Puma
|
|
71
72
|
attr_accessor :out_of_band_hook # @version 5.0.0
|
72
73
|
|
73
74
|
def self.clean_thread_locals
|
74
|
-
Thread.current.keys.each do |key| # rubocop: disable
|
75
|
+
Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods
|
75
76
|
Thread.current[key] = nil unless key == :__recursive_key__
|
76
77
|
end
|
77
78
|
end
|
@@ -101,7 +102,7 @@ module Puma
|
|
101
102
|
@spawned += 1
|
102
103
|
|
103
104
|
th = Thread.new(@spawned) do |spawned|
|
104
|
-
Puma.set_thread_name '
|
105
|
+
Puma.set_thread_name '%s tp %03i' % [@name, spawned]
|
105
106
|
todo = @todo
|
106
107
|
block = @block
|
107
108
|
mutex = @mutex
|
@@ -119,6 +120,7 @@ module Puma
|
|
119
120
|
@trim_requested -= 1
|
120
121
|
@spawned -= 1
|
121
122
|
@workers.delete th
|
123
|
+
not_full.signal
|
122
124
|
Thread.exit
|
123
125
|
end
|
124
126
|
|
@@ -220,7 +222,7 @@ module Puma
|
|
220
222
|
# then the `@todo` array would stay the same size as the reactor works
|
221
223
|
# to try to buffer the request. In that scenario the next call to this
|
222
224
|
# method would not block and another request would be added into the reactor
|
223
|
-
# by the server. This would continue until a fully
|
225
|
+
# by the server. This would continue until a fully buffered request
|
224
226
|
# makes it through the reactor and can then be processed by the thread pool.
|
225
227
|
def wait_until_not_full
|
226
228
|
with_mutex do
|
@@ -240,11 +242,12 @@ module Puma
|
|
240
242
|
|
241
243
|
# @version 5.0.0
|
242
244
|
def wait_for_less_busy_worker(delay_s)
|
245
|
+
return unless delay_s && delay_s > 0
|
246
|
+
|
243
247
|
# Ruby MRI does GVL, this can result
|
244
248
|
# in processing contention when multiple threads
|
245
249
|
# (requests) are running concurrently
|
246
250
|
return unless Puma.mri?
|
247
|
-
return unless delay_s > 0
|
248
251
|
|
249
252
|
with_mutex do
|
250
253
|
return if @shutdown
|
@@ -317,12 +320,12 @@ module Puma
|
|
317
320
|
end
|
318
321
|
|
319
322
|
def auto_trim!(timeout=30)
|
320
|
-
@auto_trim = Automaton.new(self, timeout, "threadpool trimmer", :trim)
|
323
|
+
@auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
|
321
324
|
@auto_trim.start!
|
322
325
|
end
|
323
326
|
|
324
327
|
def auto_reap!(timeout=5)
|
325
|
-
@reaper = Automaton.new(self, timeout, "threadpool reaper", :reap)
|
328
|
+
@reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
|
326
329
|
@reaper.start!
|
327
330
|
end
|
328
331
|
|
data/lib/puma/util.rb
CHANGED
@@ -10,6 +10,13 @@ module Puma
|
|
10
10
|
IO.pipe
|
11
11
|
end
|
12
12
|
|
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
|
+
|
13
20
|
# Unescapes a URI escaped string with +encoding+. +encoding+ will be the
|
14
21
|
# target encoding of the string returned, and it defaults to UTF-8
|
15
22
|
if defined?(::Encoding)
|
@@ -61,7 +68,7 @@ module Puma
|
|
61
68
|
end
|
62
69
|
end
|
63
70
|
|
64
|
-
|
71
|
+
params
|
65
72
|
end
|
66
73
|
|
67
74
|
# A case-insensitive Hash that preserves the original case of a
|
data/lib/puma.rb
CHANGED
@@ -12,12 +12,47 @@ require 'thread'
|
|
12
12
|
|
13
13
|
require 'puma/puma_http11'
|
14
14
|
require 'puma/detect'
|
15
|
+
require 'puma/json_serialization'
|
15
16
|
|
16
17
|
module Puma
|
17
18
|
autoload :Const, 'puma/const'
|
18
19
|
autoload :Server, 'puma/server'
|
19
20
|
autoload :Launcher, 'puma/launcher'
|
20
21
|
|
22
|
+
# at present, MiniSSL::Engine is only defined in extension code (puma_http11),
|
23
|
+
# not in minissl.rb
|
24
|
+
HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
|
25
|
+
|
26
|
+
HAS_UNIX_SOCKET = Object.const_defined? :UNIXSocket
|
27
|
+
|
28
|
+
if HAS_SSL
|
29
|
+
require 'puma/minissl'
|
30
|
+
else
|
31
|
+
module MiniSSL
|
32
|
+
# this class is defined so that it exists when Puma is compiled
|
33
|
+
# without ssl support, as Server and Reactor use it in rescue statements.
|
34
|
+
class SSLError < StandardError ; end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.ssl?
|
39
|
+
HAS_SSL
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.abstract_unix_socket?
|
43
|
+
@abstract_unix ||=
|
44
|
+
if HAS_UNIX_SOCKET
|
45
|
+
begin
|
46
|
+
::UNIXServer.new("\0puma.temp.unix").close
|
47
|
+
true
|
48
|
+
rescue ArgumentError # darwin
|
49
|
+
false
|
50
|
+
end
|
51
|
+
else
|
52
|
+
false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
21
56
|
# @!attribute [rw] stats_object=
|
22
57
|
def self.stats_object=(val)
|
23
58
|
@get_stats = val
|
@@ -25,8 +60,7 @@ module Puma
|
|
25
60
|
|
26
61
|
# @!attribute [rw] stats_object
|
27
62
|
def self.stats
|
28
|
-
|
29
|
-
@get_stats.stats.to_json
|
63
|
+
Puma::JSONSerialization.generate @get_stats.stats
|
30
64
|
end
|
31
65
|
|
32
66
|
# @!attribute [r] stats_hash
|
@@ -40,12 +74,4 @@ module Puma
|
|
40
74
|
return unless Thread.current.respond_to?(:name=)
|
41
75
|
Thread.current.name = "puma #{name}"
|
42
76
|
end
|
43
|
-
|
44
|
-
unless HAS_SSL
|
45
|
-
module MiniSSL
|
46
|
-
# this class is defined so that it exists when Puma is compiled
|
47
|
-
# without ssl support, as Server and Reactor use it in rescue statements.
|
48
|
-
class SSLError < StandardError ; end
|
49
|
-
end
|
50
|
-
end
|
51
77
|
end
|
data/lib/rack/handler/puma.rb
CHANGED
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: 5.
|
4
|
+
version: 5.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
|
-
autorequire:
|
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
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- bin/puma-wild
|
45
45
|
- bin/pumactl
|
46
46
|
- docs/architecture.md
|
47
|
+
- docs/compile_options.md
|
47
48
|
- docs/deployment.md
|
48
49
|
- docs/fork_worker.md
|
49
50
|
- docs/images/puma-connection-flow-no-reactor.png
|
@@ -53,10 +54,13 @@ files:
|
|
53
54
|
- docs/jungle/rc.d/README.md
|
54
55
|
- docs/jungle/rc.d/puma
|
55
56
|
- docs/jungle/rc.d/puma.conf
|
57
|
+
- docs/kubernetes.md
|
56
58
|
- docs/nginx.md
|
57
59
|
- docs/plugins.md
|
60
|
+
- docs/rails_dev_mode.md
|
58
61
|
- docs/restart.md
|
59
62
|
- docs/signals.md
|
63
|
+
- docs/stats.md
|
60
64
|
- docs/systemd.md
|
61
65
|
- ext/puma_http11/PumaHttp11Service.java
|
62
66
|
- ext/puma_http11/ext_help.h
|
@@ -90,6 +94,7 @@ files:
|
|
90
94
|
- lib/puma/events.rb
|
91
95
|
- lib/puma/io_buffer.rb
|
92
96
|
- lib/puma/jruby_restart.rb
|
97
|
+
- lib/puma/json_serialization.rb
|
93
98
|
- lib/puma/launcher.rb
|
94
99
|
- lib/puma/minissl.rb
|
95
100
|
- lib/puma/minissl/context_builder.rb
|
@@ -106,6 +111,7 @@ files:
|
|
106
111
|
- lib/puma/server.rb
|
107
112
|
- lib/puma/single.rb
|
108
113
|
- lib/puma/state_file.rb
|
114
|
+
- lib/puma/systemd.rb
|
109
115
|
- lib/puma/thread_pool.rb
|
110
116
|
- lib/puma/util.rb
|
111
117
|
- lib/rack/handler/puma.rb
|
@@ -119,7 +125,7 @@ metadata:
|
|
119
125
|
changelog_uri: https://github.com/puma/puma/blob/master/History.md
|
120
126
|
homepage_uri: https://puma.io
|
121
127
|
source_code_uri: https://github.com/puma/puma
|
122
|
-
post_install_message:
|
128
|
+
post_install_message:
|
123
129
|
rdoc_options: []
|
124
130
|
require_paths:
|
125
131
|
- lib
|
@@ -134,9 +140,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
140
|
- !ruby/object:Gem::Version
|
135
141
|
version: '0'
|
136
142
|
requirements: []
|
137
|
-
rubygems_version: 3.
|
138
|
-
signing_key:
|
143
|
+
rubygems_version: 3.2.26
|
144
|
+
signing_key:
|
139
145
|
specification_version: 4
|
140
|
-
summary: Puma is a simple, fast, threaded, and highly
|
146
|
+
summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
|
141
147
|
Ruby/Rack applications
|
142
148
|
test_files: []
|