puma 4.3.12 → 6.0.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 +1591 -521
- data/LICENSE +23 -20
- data/README.md +130 -42
- data/bin/puma-wild +3 -9
- data/docs/architecture.md +63 -26
- data/docs/compile_options.md +55 -0
- data/docs/deployment.md +60 -69
- data/docs/fork_worker.md +31 -0
- data/docs/jungle/README.md +9 -0
- data/{tools → docs}/jungle/rc.d/README.md +1 -1
- data/{tools → docs}/jungle/rc.d/puma +2 -2
- data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +66 -0
- data/docs/nginx.md +1 -1
- data/docs/plugins.md +15 -15
- data/docs/rails_dev_mode.md +28 -0
- data/docs/restart.md +46 -23
- data/docs/signals.md +13 -11
- data/docs/stats.md +142 -0
- data/docs/systemd.md +85 -128
- 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 +2 -4
- data/ext/puma_http11/ext_help.h +1 -1
- data/ext/puma_http11/extconf.rb +49 -12
- data/ext/puma_http11/http11_parser.c +46 -48
- data/ext/puma_http11/http11_parser.h +2 -2
- data/ext/puma_http11/http11_parser.java.rl +3 -3
- data/ext/puma_http11/http11_parser.rl +3 -3
- data/ext/puma_http11/http11_parser_common.rl +2 -2
- data/ext/puma_http11/mini_ssl.c +250 -93
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +6 -6
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +4 -6
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +241 -96
- data/ext/puma_http11/puma_http11.c +46 -57
- data/lib/puma/app/status.rb +52 -38
- data/lib/puma/binder.rb +232 -119
- data/lib/puma/cli.rb +33 -33
- data/lib/puma/client.rb +125 -87
- data/lib/puma/cluster/worker.rb +175 -0
- data/lib/puma/cluster/worker_handle.rb +97 -0
- data/lib/puma/cluster.rb +224 -229
- data/lib/puma/commonlogger.rb +2 -2
- data/lib/puma/configuration.rb +112 -87
- data/lib/puma/const.rb +25 -22
- data/lib/puma/control_cli.rb +99 -79
- data/lib/puma/detect.rb +31 -2
- data/lib/puma/dsl.rb +423 -110
- data/lib/puma/error_logger.rb +112 -0
- data/lib/puma/events.rb +16 -115
- data/lib/puma/io_buffer.rb +34 -2
- data/lib/puma/jruby_restart.rb +2 -59
- data/lib/puma/json_serialization.rb +96 -0
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +170 -148
- data/lib/puma/log_writer.rb +137 -0
- data/lib/puma/minissl/context_builder.rb +35 -19
- data/lib/puma/minissl.rb +213 -55
- data/lib/puma/null_io.rb +18 -1
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/plugin.rb +3 -12
- data/lib/puma/rack/builder.rb +5 -9
- data/lib/puma/rack_default.rb +1 -1
- data/lib/puma/reactor.rb +85 -369
- data/lib/puma/request.rb +607 -0
- data/lib/puma/runner.rb +83 -77
- data/lib/puma/server.rb +305 -789
- data/lib/puma/single.rb +18 -74
- data/lib/puma/state_file.rb +45 -8
- data/lib/puma/systemd.rb +47 -0
- data/lib/puma/thread_pool.rb +137 -66
- data/lib/puma/util.rb +21 -4
- data/lib/puma.rb +54 -5
- data/lib/rack/handler/puma.rb +11 -12
- data/tools/{docker/Dockerfile → Dockerfile} +1 -1
- metadata +31 -23
- data/docs/tcp_mode.md +0 -96
- data/ext/puma_http11/io_buffer.c +0 -155
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -72
- data/lib/puma/accept_nonblock.rb +0 -29
- data/lib/puma/tcp_logger.rb +0 -41
- data/tools/jungle/README.md +0 -19
- data/tools/jungle/init.d/README.md +0 -61
- data/tools/jungle/init.d/puma +0 -421
- data/tools/jungle/init.d/run-puma +0 -18
- data/tools/jungle/upstart/README.md +0 -61
- data/tools/jungle/upstart/puma-manager.conf +0 -31
- data/tools/jungle/upstart/puma.conf +0 -69
data/lib/puma/runner.rb
CHANGED
@@ -1,25 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'puma/minissl/context_builder'
|
3
|
+
require_relative 'server'
|
4
|
+
require_relative 'const'
|
6
5
|
|
7
6
|
module Puma
|
8
7
|
# Generic class that is used by `Puma::Cluster` and `Puma::Single` to
|
9
8
|
# serve requests. This class spawns a new instance of `Puma::Server` via
|
10
9
|
# a call to `start_server`.
|
11
10
|
class Runner
|
12
|
-
def initialize(
|
13
|
-
@launcher =
|
14
|
-
@
|
15
|
-
@
|
11
|
+
def initialize(launcher)
|
12
|
+
@launcher = launcher
|
13
|
+
@log_writer = launcher.log_writer
|
14
|
+
@events = launcher.events
|
15
|
+
@config = launcher.config
|
16
|
+
@options = launcher.options
|
16
17
|
@app = nil
|
17
18
|
@control = nil
|
18
19
|
@started_at = Time.now
|
20
|
+
@wakeup = nil
|
19
21
|
end
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
+
# Returns the hash of configuration options.
|
24
|
+
# @return [Puma::UserFileDefaultOptions]
|
25
|
+
attr_reader :options
|
26
|
+
|
27
|
+
def wakeup!
|
28
|
+
return unless @wakeup
|
29
|
+
|
30
|
+
@wakeup.write "!" unless @wakeup.closed?
|
31
|
+
|
32
|
+
rescue SystemCallError, IOError
|
33
|
+
Puma::Util.purge_interrupt_queue
|
23
34
|
end
|
24
35
|
|
25
36
|
def development?
|
@@ -31,28 +42,27 @@ module Puma
|
|
31
42
|
end
|
32
43
|
|
33
44
|
def log(str)
|
34
|
-
@
|
45
|
+
@log_writer.log str
|
35
46
|
end
|
36
47
|
|
37
|
-
|
38
|
-
|
48
|
+
# @version 5.0.0
|
49
|
+
def stop_control
|
50
|
+
@control&.stop true
|
39
51
|
end
|
40
52
|
|
41
53
|
def error(str)
|
42
|
-
@
|
54
|
+
@log_writer.error str
|
43
55
|
end
|
44
56
|
|
45
57
|
def debug(str)
|
46
|
-
@
|
58
|
+
@log_writer.log "- #{str}" if @options[:debug]
|
47
59
|
end
|
48
60
|
|
49
61
|
def start_control
|
50
62
|
str = @options[:control_url]
|
51
63
|
return unless str
|
52
64
|
|
53
|
-
|
54
|
-
|
55
|
-
uri = URI.parse str
|
65
|
+
require_relative 'app/status'
|
56
66
|
|
57
67
|
if token = @options[:control_auth_token]
|
58
68
|
token = nil if token.empty? || token == 'none'
|
@@ -60,34 +70,23 @@ module Puma
|
|
60
70
|
|
61
71
|
app = Puma::App::Status.new @launcher, token
|
62
72
|
|
63
|
-
|
64
|
-
control
|
65
|
-
control
|
66
|
-
|
67
|
-
case uri.scheme
|
68
|
-
when "ssl"
|
69
|
-
log "* Starting control server on #{str}"
|
70
|
-
params = Util.parse_query uri.query
|
71
|
-
ctx = MiniSSL::ContextBuilder.new(params, @events).context
|
72
|
-
|
73
|
-
control.add_ssl_listener uri.host, uri.port, ctx
|
74
|
-
when "tcp"
|
75
|
-
log "* Starting control server on #{str}"
|
76
|
-
control.add_tcp_listener uri.host, uri.port
|
77
|
-
when "unix"
|
78
|
-
log "* Starting control server on #{str}"
|
79
|
-
path = "#{uri.host}#{uri.path}"
|
80
|
-
mask = @options[:control_url_umask]
|
81
|
-
|
82
|
-
control.add_unix_listener path, mask
|
83
|
-
else
|
84
|
-
error "Invalid control URI: #{str}"
|
85
|
-
end
|
73
|
+
# A Reactor is not created aand nio4r is not loaded when 'queue_requests: false'
|
74
|
+
# Use `nil` for events, no hooks in control server
|
75
|
+
control = Puma::Server.new app, nil,
|
76
|
+
{ min_threads: 0, max_threads: 1, queue_requests: false, log_writer: @log_writer }
|
86
77
|
|
87
|
-
control.
|
78
|
+
control.binder.parse [str], nil, 'Starting control server'
|
79
|
+
|
80
|
+
control.run thread_name: 'ctl'
|
88
81
|
@control = control
|
89
82
|
end
|
90
83
|
|
84
|
+
# @version 5.0.0
|
85
|
+
def close_control_listeners
|
86
|
+
@control.binder.close_listeners if @control
|
87
|
+
end
|
88
|
+
|
89
|
+
# @!attribute [r] ruby_engine
|
91
90
|
def ruby_engine
|
92
91
|
if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby"
|
93
92
|
"ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
|
@@ -103,14 +102,18 @@ module Puma
|
|
103
102
|
def output_header(mode)
|
104
103
|
min_t = @options[:min_threads]
|
105
104
|
max_t = @options[:max_threads]
|
105
|
+
environment = @options[:environment]
|
106
106
|
|
107
107
|
log "Puma starting in #{mode} mode..."
|
108
|
-
log "*
|
109
|
-
log "*
|
110
|
-
log "*
|
108
|
+
log "* Puma version: #{Puma::Const::PUMA_VERSION} (#{ruby_engine}) (\"#{Puma::Const::CODE_NAME}\")"
|
109
|
+
log "* Min threads: #{min_t}"
|
110
|
+
log "* Max threads: #{max_t}"
|
111
|
+
log "* Environment: #{environment}"
|
111
112
|
|
112
|
-
if
|
113
|
-
log "*
|
113
|
+
if mode == "cluster"
|
114
|
+
log "* Master PID: #{Process.pid}"
|
115
|
+
else
|
116
|
+
log "* PID: #{Process.pid}"
|
114
117
|
end
|
115
118
|
end
|
116
119
|
|
@@ -124,69 +127,72 @@ module Puma
|
|
124
127
|
append = @options[:redirect_append]
|
125
128
|
|
126
129
|
if stdout
|
127
|
-
|
128
|
-
raise "Cannot redirect STDOUT to #{stdout}"
|
129
|
-
end
|
130
|
+
ensure_output_directory_exists(stdout, 'STDOUT')
|
130
131
|
|
131
132
|
STDOUT.reopen stdout, (append ? "a" : "w")
|
132
|
-
STDOUT.sync = true
|
133
133
|
STDOUT.puts "=== puma startup: #{Time.now} ==="
|
134
|
+
STDOUT.flush unless STDOUT.sync
|
134
135
|
end
|
135
136
|
|
136
137
|
if stderr
|
137
|
-
|
138
|
-
raise "Cannot redirect STDERR to #{stderr}"
|
139
|
-
end
|
138
|
+
ensure_output_directory_exists(stderr, 'STDERR')
|
140
139
|
|
141
140
|
STDERR.reopen stderr, (append ? "a" : "w")
|
142
|
-
STDERR.sync = true
|
143
141
|
STDERR.puts "=== puma startup: #{Time.now} ==="
|
142
|
+
STDERR.flush unless STDERR.sync
|
143
|
+
end
|
144
|
+
|
145
|
+
if @options[:mutate_stdout_and_stderr_to_sync_on_write]
|
146
|
+
STDOUT.sync = true
|
147
|
+
STDERR.sync = true
|
144
148
|
end
|
145
149
|
end
|
146
150
|
|
147
151
|
def load_and_bind
|
148
|
-
unless @
|
152
|
+
unless @config.app_configured?
|
149
153
|
error "No application configured, nothing to run"
|
150
154
|
exit 1
|
151
155
|
end
|
152
156
|
|
153
|
-
# Load the app before we daemonize.
|
154
157
|
begin
|
155
|
-
@app = @
|
158
|
+
@app = @config.app
|
156
159
|
rescue Exception => e
|
157
160
|
log "! Unable to load application: #{e.class}: #{e.message}"
|
158
161
|
raise e
|
159
162
|
end
|
160
163
|
|
161
|
-
@launcher.binder.parse @options[:binds]
|
164
|
+
@launcher.binder.parse @options[:binds]
|
162
165
|
end
|
163
166
|
|
167
|
+
# @!attribute [r] app
|
164
168
|
def app
|
165
|
-
@app ||= @
|
169
|
+
@app ||= @config.app
|
166
170
|
end
|
167
171
|
|
168
172
|
def start_server
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
server.min_threads = min_t
|
174
|
-
server.max_threads = max_t
|
175
|
-
server.inherit_binder @launcher.binder
|
176
|
-
|
177
|
-
if @options[:mode] == :tcp
|
178
|
-
server.tcp_mode!
|
179
|
-
end
|
180
|
-
|
181
|
-
if @options[:early_hints]
|
182
|
-
server.early_hints = true
|
183
|
-
end
|
173
|
+
server = Puma::Server.new(app, @events, @options)
|
174
|
+
server.inherit_binder(@launcher.binder)
|
175
|
+
server
|
176
|
+
end
|
184
177
|
|
185
|
-
|
186
|
-
|
178
|
+
private
|
179
|
+
def ensure_output_directory_exists(path, io_name)
|
180
|
+
unless Dir.exist?(File.dirname(path))
|
181
|
+
raise "Cannot redirect #{io_name} to #{path}"
|
187
182
|
end
|
183
|
+
end
|
188
184
|
|
189
|
-
|
185
|
+
def stats
|
186
|
+
{
|
187
|
+
versions: {
|
188
|
+
puma: Puma::Const::PUMA_VERSION,
|
189
|
+
ruby: {
|
190
|
+
engine: RUBY_ENGINE,
|
191
|
+
version: RUBY_VERSION,
|
192
|
+
patchlevel: RUBY_PATCHLEVEL
|
193
|
+
}
|
194
|
+
}
|
195
|
+
}
|
190
196
|
end
|
191
197
|
end
|
192
198
|
end
|