puma 5.6.9 → 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 +96 -28
- data/LICENSE +0 -0
- data/README.md +21 -17
- data/bin/puma-wild +1 -1
- data/docs/architecture.md +0 -0
- data/docs/compile_options.md +34 -0
- data/docs/deployment.md +0 -0
- 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 +0 -0
- data/docs/rails_dev_mode.md +0 -0
- data/docs/restart.md +0 -0
- data/docs/signals.md +0 -0
- data/docs/stats.md +0 -0
- data/docs/systemd.md +0 -0
- 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 +11 -8
- 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 +36 -15
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +3 -5
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +156 -53
- data/ext/puma_http11/puma_http11.c +17 -9
- data/lib/puma/app/status.rb +3 -3
- data/lib/puma/binder.rb +36 -42
- data/lib/puma/cli.rb +11 -17
- data/lib/puma/client.rb +29 -53
- data/lib/puma/cluster/worker.rb +13 -11
- data/lib/puma/cluster/worker_handle.rb +4 -1
- data/lib/puma/cluster.rb +28 -25
- data/lib/puma/commonlogger.rb +0 -0
- data/lib/puma/configuration.rb +74 -58
- data/lib/puma/const.rb +14 -26
- data/lib/puma/control_cli.rb +3 -6
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +93 -52
- 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_serialization.rb +0 -0
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +96 -156
- data/lib/puma/log_writer.rb +137 -0
- data/lib/puma/minissl/context_builder.rb +23 -12
- data/lib/puma/minissl.rb +82 -11
- data/lib/puma/null_io.rb +0 -0
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/plugin.rb +0 -0
- data/lib/puma/rack/builder.rb +4 -4
- 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 +295 -177
- data/lib/puma/runner.rb +41 -20
- data/lib/puma/server.rb +53 -66
- data/lib/puma/single.rb +10 -10
- data/lib/puma/state_file.rb +1 -4
- data/lib/puma/systemd.rb +3 -2
- data/lib/puma/thread_pool.rb +16 -13
- data/lib/puma/util.rb +0 -11
- data/lib/puma.rb +10 -9
- data/lib/rack/handler/puma.rb +9 -9
- data/tools/Dockerfile +0 -0
- data/tools/trickletest.rb +0 -0
- metadata +9 -6
- data/lib/puma/queue_close.rb +0 -26
- data/lib/rack/version_restriction.rb +0 -15
data/lib/puma/runner.rb
CHANGED
@@ -1,23 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require_relative 'server'
|
4
|
+
require_relative 'const'
|
5
5
|
|
6
6
|
module Puma
|
7
7
|
# Generic class that is used by `Puma::Cluster` and `Puma::Single` to
|
8
8
|
# serve requests. This class spawns a new instance of `Puma::Server` via
|
9
9
|
# a call to `start_server`.
|
10
10
|
class Runner
|
11
|
-
def initialize(
|
12
|
-
@launcher =
|
13
|
-
@
|
14
|
-
@
|
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
|
15
17
|
@app = nil
|
16
18
|
@control = nil
|
17
19
|
@started_at = Time.now
|
18
20
|
@wakeup = nil
|
19
21
|
end
|
20
22
|
|
23
|
+
# Returns the hash of configuration options.
|
24
|
+
# @return [Puma::UserFileDefaultOptions]
|
25
|
+
attr_reader :options
|
26
|
+
|
21
27
|
def wakeup!
|
22
28
|
return unless @wakeup
|
23
29
|
|
@@ -36,27 +42,27 @@ module Puma
|
|
36
42
|
end
|
37
43
|
|
38
44
|
def log(str)
|
39
|
-
@
|
45
|
+
@log_writer.log str
|
40
46
|
end
|
41
47
|
|
42
48
|
# @version 5.0.0
|
43
49
|
def stop_control
|
44
|
-
@control
|
50
|
+
@control&.stop true
|
45
51
|
end
|
46
52
|
|
47
53
|
def error(str)
|
48
|
-
@
|
54
|
+
@log_writer.error str
|
49
55
|
end
|
50
56
|
|
51
57
|
def debug(str)
|
52
|
-
@
|
58
|
+
@log_writer.log "- #{str}" if @options[:debug]
|
53
59
|
end
|
54
60
|
|
55
61
|
def start_control
|
56
62
|
str = @options[:control_url]
|
57
63
|
return unless str
|
58
64
|
|
59
|
-
|
65
|
+
require_relative 'app/status'
|
60
66
|
|
61
67
|
if token = @options[:control_auth_token]
|
62
68
|
token = nil if token.empty? || token == 'none'
|
@@ -64,10 +70,12 @@ module Puma
|
|
64
70
|
|
65
71
|
app = Puma::App::Status.new @launcher, token
|
66
72
|
|
67
|
-
|
68
|
-
|
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 }
|
69
77
|
|
70
|
-
control.binder.parse [str],
|
78
|
+
control.binder.parse [str], nil, 'Starting control server'
|
71
79
|
|
72
80
|
control.run thread_name: 'ctl'
|
73
81
|
@control = control
|
@@ -141,29 +149,29 @@ module Puma
|
|
141
149
|
end
|
142
150
|
|
143
151
|
def load_and_bind
|
144
|
-
unless @
|
152
|
+
unless @config.app_configured?
|
145
153
|
error "No application configured, nothing to run"
|
146
154
|
exit 1
|
147
155
|
end
|
148
156
|
|
149
157
|
begin
|
150
|
-
@app = @
|
158
|
+
@app = @config.app
|
151
159
|
rescue Exception => e
|
152
160
|
log "! Unable to load application: #{e.class}: #{e.message}"
|
153
161
|
raise e
|
154
162
|
end
|
155
163
|
|
156
|
-
@launcher.binder.parse @options[:binds]
|
164
|
+
@launcher.binder.parse @options[:binds]
|
157
165
|
end
|
158
166
|
|
159
167
|
# @!attribute [r] app
|
160
168
|
def app
|
161
|
-
@app ||= @
|
169
|
+
@app ||= @config.app
|
162
170
|
end
|
163
171
|
|
164
172
|
def start_server
|
165
|
-
server = Puma::Server.new
|
166
|
-
server.inherit_binder
|
173
|
+
server = Puma::Server.new(app, @events, @options)
|
174
|
+
server.inherit_binder(@launcher.binder)
|
167
175
|
server
|
168
176
|
end
|
169
177
|
|
@@ -173,5 +181,18 @@ module Puma
|
|
173
181
|
raise "Cannot redirect #{io_name} to #{path}"
|
174
182
|
end
|
175
183
|
end
|
184
|
+
|
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
|
+
}
|
196
|
+
end
|
176
197
|
end
|
177
198
|
end
|
data/lib/puma/server.rb
CHANGED
@@ -2,19 +2,20 @@
|
|
2
2
|
|
3
3
|
require 'stringio'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
require_relative 'thread_pool'
|
6
|
+
require_relative 'const'
|
7
|
+
require_relative 'log_writer'
|
8
|
+
require_relative 'events'
|
9
|
+
require_relative 'null_io'
|
10
|
+
require_relative 'reactor'
|
11
|
+
require_relative 'client'
|
12
|
+
require_relative 'binder'
|
13
|
+
require_relative 'util'
|
14
|
+
require_relative 'io_buffer'
|
15
|
+
require_relative 'request'
|
15
16
|
|
16
17
|
require 'socket'
|
17
|
-
require 'io/wait'
|
18
|
+
require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT
|
18
19
|
require 'forwardable'
|
19
20
|
|
20
21
|
module Puma
|
@@ -30,27 +31,21 @@ module Puma
|
|
30
31
|
#
|
31
32
|
# Each `Puma::Server` will have one reactor and one thread pool.
|
32
33
|
class Server
|
33
|
-
|
34
34
|
include Puma::Const
|
35
35
|
include Request
|
36
36
|
extend Forwardable
|
37
37
|
|
38
38
|
attr_reader :thread
|
39
|
+
attr_reader :log_writer
|
39
40
|
attr_reader :events
|
40
41
|
attr_reader :min_threads, :max_threads # for #stats
|
41
42
|
attr_reader :requests_count # @version 5.0.0
|
42
|
-
attr_reader :log_writer # to help with backports
|
43
43
|
|
44
44
|
# @todo the following may be deprecated in the future
|
45
45
|
attr_reader :auto_trim_time, :early_hints, :first_data_timeout,
|
46
46
|
:leak_stack_on_error,
|
47
47
|
:persistent_timeout, :reaping_time
|
48
48
|
|
49
|
-
# @deprecated v6.0.0
|
50
|
-
attr_writer :auto_trim_time, :early_hints, :first_data_timeout,
|
51
|
-
:leak_stack_on_error, :min_threads, :max_threads,
|
52
|
-
:persistent_timeout, :reaping_time
|
53
|
-
|
54
49
|
attr_accessor :app
|
55
50
|
attr_accessor :binder
|
56
51
|
|
@@ -61,8 +56,9 @@ module Puma
|
|
61
56
|
|
62
57
|
# Create a server for the rack app +app+.
|
63
58
|
#
|
64
|
-
# +
|
65
|
-
#
|
59
|
+
# +log_writer+ is a Puma::LogWriter object used to log info and error messages.
|
60
|
+
#
|
61
|
+
# +events+ is a Puma::Events object used to notify application status events.
|
66
62
|
#
|
67
63
|
# Server#run returns a thread that you can join on to wait for the server
|
68
64
|
# to do its work.
|
@@ -71,35 +67,40 @@ module Puma
|
|
71
67
|
# and have default values set via +fetch+. Normally the values are set via
|
72
68
|
# `::Puma::Configuration.puma_default_options`.
|
73
69
|
#
|
74
|
-
|
70
|
+
# @note The `events` parameter is set to nil, and set to `Events.new` in code.
|
71
|
+
# Often `options` needs to be passed, but `events` does not. Using nil allows
|
72
|
+
# calling code to not require events.rb.
|
73
|
+
#
|
74
|
+
def initialize(app, events = nil, options = {})
|
75
75
|
@app = app
|
76
|
-
@events = events
|
77
|
-
@log_writer = events
|
76
|
+
@events = events || Events.new
|
78
77
|
|
79
78
|
@check, @notify = nil
|
80
79
|
@status = :stop
|
81
80
|
|
82
|
-
@auto_trim_time = 30
|
83
|
-
@reaping_time = 1
|
84
|
-
|
85
81
|
@thread = nil
|
86
82
|
@thread_pool = nil
|
87
83
|
|
88
|
-
@options = options
|
84
|
+
@options = if options.is_a?(UserFileDefaultOptions)
|
85
|
+
options
|
86
|
+
else
|
87
|
+
UserFileDefaultOptions.new(options, Configuration::DEFAULTS)
|
88
|
+
end
|
89
89
|
|
90
|
-
@
|
91
|
-
@
|
92
|
-
@
|
93
|
-
@
|
94
|
-
@
|
95
|
-
@
|
96
|
-
@
|
97
|
-
@
|
90
|
+
@log_writer = @options.fetch :log_writer, LogWriter.stdio
|
91
|
+
@early_hints = @options[:early_hints]
|
92
|
+
@first_data_timeout = @options[:first_data_timeout]
|
93
|
+
@min_threads = @options[:min_threads]
|
94
|
+
@max_threads = @options[:max_threads]
|
95
|
+
@persistent_timeout = @options[:persistent_timeout]
|
96
|
+
@queue_requests = @options[:queue_requests]
|
97
|
+
@max_fast_inline = @options[:max_fast_inline]
|
98
|
+
@io_selector_backend = @options[:io_selector_backend]
|
98
99
|
|
99
100
|
temp = !!(@options[:environment] =~ /\A(development|test)\z/)
|
100
101
|
@leak_stack_on_error = @options[:environment] ? temp : true
|
101
102
|
|
102
|
-
@binder = Binder.new(
|
103
|
+
@binder = Binder.new(log_writer)
|
103
104
|
|
104
105
|
ENV['RACK_ENV'] ||= "development"
|
105
106
|
|
@@ -195,12 +196,12 @@ module Puma
|
|
195
196
|
|
196
197
|
# @!attribute [r] backlog
|
197
198
|
def backlog
|
198
|
-
@thread_pool
|
199
|
+
@thread_pool&.backlog
|
199
200
|
end
|
200
201
|
|
201
202
|
# @!attribute [r] running
|
202
203
|
def running
|
203
|
-
@thread_pool
|
204
|
+
@thread_pool&.spawned
|
204
205
|
end
|
205
206
|
|
206
207
|
|
@@ -213,7 +214,7 @@ module Puma
|
|
213
214
|
# value would be 4 until it finishes processing.
|
214
215
|
# @!attribute [r] pool_capacity
|
215
216
|
def pool_capacity
|
216
|
-
@thread_pool
|
217
|
+
@thread_pool&.pool_capacity
|
217
218
|
end
|
218
219
|
|
219
220
|
# Runs the server.
|
@@ -229,29 +230,16 @@ module Puma
|
|
229
230
|
|
230
231
|
@status = :run
|
231
232
|
|
232
|
-
@thread_pool = ThreadPool.new(
|
233
|
-
thread_name,
|
234
|
-
@min_threads,
|
235
|
-
@max_threads,
|
236
|
-
::Puma::IOBuffer,
|
237
|
-
&method(:process_client)
|
238
|
-
)
|
239
|
-
|
240
|
-
@thread_pool.out_of_band_hook = @options[:out_of_band]
|
241
|
-
@thread_pool.clean_thread_locals = @options[:clean_thread_locals]
|
233
|
+
@thread_pool = ThreadPool.new(thread_name, @options) { |a, b| process_client a, b }
|
242
234
|
|
243
235
|
if @queue_requests
|
244
|
-
@reactor = Reactor.new(@io_selector_backend
|
236
|
+
@reactor = Reactor.new(@io_selector_backend) { |c| reactor_wakeup c }
|
245
237
|
@reactor.run
|
246
238
|
end
|
247
239
|
|
248
|
-
if @reaping_time
|
249
|
-
@thread_pool.auto_reap!(@reaping_time)
|
250
|
-
end
|
251
240
|
|
252
|
-
if @
|
253
|
-
|
254
|
-
end
|
241
|
+
@thread_pool.auto_reap! if @options[:reaping_time]
|
242
|
+
@thread_pool.auto_trim! if @options[:auto_trim_time]
|
255
243
|
|
256
244
|
@check, @notify = Puma::Util.pipe unless @notify
|
257
245
|
|
@@ -355,11 +343,11 @@ module Puma
|
|
355
343
|
# In the case that any of the sockets are unexpectedly close.
|
356
344
|
raise
|
357
345
|
rescue StandardError => e
|
358
|
-
@
|
346
|
+
@log_writer.unknown_error e, nil, "Listen loop"
|
359
347
|
end
|
360
348
|
end
|
361
349
|
|
362
|
-
@
|
350
|
+
@log_writer.debug "Drained #{drain} additional connections." if drain
|
363
351
|
@events.fire :state, @status
|
364
352
|
|
365
353
|
if queue_requests
|
@@ -368,14 +356,13 @@ module Puma
|
|
368
356
|
end
|
369
357
|
graceful_shutdown if @status == :stop || @status == :restart
|
370
358
|
rescue Exception => e
|
371
|
-
@
|
359
|
+
@log_writer.unknown_error e, nil, "Exception handling servers"
|
372
360
|
ensure
|
373
|
-
# RuntimeError is Ruby 2.2 issue, can't modify frozen IOError
|
374
361
|
# Errno::EBADF is infrequently raised
|
375
362
|
[@check, @notify].each do |io|
|
376
363
|
begin
|
377
364
|
io.close unless io.closed?
|
378
|
-
rescue Errno::EBADF
|
365
|
+
rescue Errno::EBADF
|
379
366
|
end
|
380
367
|
end
|
381
368
|
@notify = nil
|
@@ -490,7 +477,7 @@ module Puma
|
|
490
477
|
Puma::Util.purge_interrupt_queue
|
491
478
|
# Already closed
|
492
479
|
rescue StandardError => e
|
493
|
-
@
|
480
|
+
@log_writer.unknown_error e, nil, "Client"
|
494
481
|
end
|
495
482
|
end
|
496
483
|
end
|
@@ -513,16 +500,16 @@ module Puma
|
|
513
500
|
lowlevel_error(e, client.env)
|
514
501
|
case e
|
515
502
|
when MiniSSL::SSLError
|
516
|
-
@
|
503
|
+
@log_writer.ssl_error e, client.io
|
517
504
|
when HttpParserError
|
518
505
|
client.write_error(400)
|
519
|
-
@
|
506
|
+
@log_writer.parse_error e, client
|
520
507
|
when HttpParserError501
|
521
508
|
client.write_error(501)
|
522
|
-
@
|
509
|
+
@log_writer.parse_error e, client
|
523
510
|
else
|
524
511
|
client.write_error(500)
|
525
|
-
@
|
512
|
+
@log_writer.unknown_error e, nil, "Read"
|
526
513
|
end
|
527
514
|
end
|
528
515
|
|
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
|
@@ -17,25 +17,25 @@ module Puma
|
|
17
17
|
def stats
|
18
18
|
{
|
19
19
|
started_at: @started_at.utc.iso8601
|
20
|
-
}.merge(@server.stats)
|
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,7 @@ module Puma
|
|
55
55
|
log "Use Ctrl-C to stop"
|
56
56
|
redirect_io
|
57
57
|
|
58
|
-
@
|
58
|
+
@events.fire_on_booted!
|
59
59
|
|
60
60
|
begin
|
61
61
|
server_thread.join
|
data/lib/puma/state_file.rb
CHANGED
@@ -15,15 +15,12 @@ module Puma
|
|
15
15
|
|
16
16
|
ALLOWED_FIELDS = %w!control_url control_auth_token pid running_from!
|
17
17
|
|
18
|
-
# @deprecated 6.0.0
|
19
|
-
FIELDS = ALLOWED_FIELDS
|
20
|
-
|
21
18
|
def initialize
|
22
19
|
@options = {}
|
23
20
|
end
|
24
21
|
|
25
22
|
def save(path, permission = nil)
|
26
|
-
contents = "---\n"
|
23
|
+
contents = +"---\n"
|
27
24
|
@options.each do |k,v|
|
28
25
|
next unless ALLOWED_FIELDS.include? k
|
29
26
|
case v
|
data/lib/puma/systemd.rb
CHANGED
@@ -4,7 +4,8 @@ require 'sd_notify'
|
|
4
4
|
|
5
5
|
module Puma
|
6
6
|
class Systemd
|
7
|
-
def initialize(events)
|
7
|
+
def initialize(log_writer, events)
|
8
|
+
@log_writer = log_writer
|
8
9
|
@events = events
|
9
10
|
end
|
10
11
|
|
@@ -40,7 +41,7 @@ module Puma
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def log(str)
|
43
|
-
@
|
44
|
+
@log_writer.log(str)
|
44
45
|
end
|
45
46
|
end
|
46
47
|
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,14 @@ 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])
|
45
47
|
@block = block
|
46
|
-
@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]
|
47
53
|
|
48
54
|
@shutdown = false
|
49
55
|
|
@@ -62,14 +68,11 @@ module Puma
|
|
62
68
|
end
|
63
69
|
end
|
64
70
|
|
65
|
-
@clean_thread_locals = false
|
66
71
|
@force_shutdown = false
|
67
72
|
@shutdown_mutex = Mutex.new
|
68
73
|
end
|
69
74
|
|
70
75
|
attr_reader :spawned, :trim_requested, :waiting
|
71
|
-
attr_accessor :clean_thread_locals
|
72
|
-
attr_accessor :out_of_band_hook # @version 5.0.0
|
73
76
|
|
74
77
|
def self.clean_thread_locals
|
75
78
|
Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods
|
@@ -160,12 +163,12 @@ module Puma
|
|
160
163
|
|
161
164
|
# @version 5.0.0
|
162
165
|
def trigger_out_of_band_hook
|
163
|
-
return false unless
|
166
|
+
return false unless @out_of_band&.any?
|
164
167
|
|
165
168
|
# we execute on idle hook when all threads are free
|
166
169
|
return false unless @spawned == @waiting
|
167
170
|
|
168
|
-
|
171
|
+
@out_of_band.each(&:call)
|
169
172
|
true
|
170
173
|
rescue Exception => e
|
171
174
|
STDERR.puts "Exception calling out_of_band_hook: #{e.message} (#{e.class})"
|
@@ -319,12 +322,12 @@ module Puma
|
|
319
322
|
end
|
320
323
|
end
|
321
324
|
|
322
|
-
def auto_trim!(timeout
|
325
|
+
def auto_trim!(timeout=@auto_trim_time)
|
323
326
|
@auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
|
324
327
|
@auto_trim.start!
|
325
328
|
end
|
326
329
|
|
327
|
-
def auto_reap!(timeout
|
330
|
+
def auto_reap!(timeout=@reaping_time)
|
328
331
|
@reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
|
329
332
|
@reaper.start!
|
330
333
|
end
|
@@ -354,8 +357,8 @@ module Puma
|
|
354
357
|
@not_empty.broadcast
|
355
358
|
@not_full.broadcast
|
356
359
|
|
357
|
-
@auto_trim
|
358
|
-
@reaper
|
360
|
+
@auto_trim&.stop
|
361
|
+
@reaper&.stop
|
359
362
|
# dup workers so that we join them all safely
|
360
363
|
@workers.dup
|
361
364
|
end
|
data/lib/puma/util.rb
CHANGED
@@ -39,17 +39,6 @@ module Puma
|
|
39
39
|
end
|
40
40
|
module_function :unescape, :escape
|
41
41
|
|
42
|
-
# @version 5.0.0
|
43
|
-
def nakayoshi_gc(events)
|
44
|
-
events.log "! Promoting existing objects to old generation..."
|
45
|
-
4.times { GC.start(full_mark: false) }
|
46
|
-
if GC.respond_to?(:compact)
|
47
|
-
events.log "! Compacting..."
|
48
|
-
GC.compact
|
49
|
-
end
|
50
|
-
events.log "! Friendly fork preparation complete."
|
51
|
-
end
|
52
|
-
|
53
42
|
DEFAULT_SEP = /[&;] */n
|
54
43
|
|
55
44
|
# Stolen from Mongrel, with some small modifications:
|
data/lib/puma.rb
CHANGED
@@ -10,25 +10,28 @@ require 'stringio'
|
|
10
10
|
|
11
11
|
require 'thread'
|
12
12
|
|
13
|
-
#
|
13
|
+
# use require, see https://github.com/puma/puma/pull/2381
|
14
14
|
require 'puma/puma_http11'
|
15
|
+
|
15
16
|
require_relative 'puma/detect'
|
16
17
|
require_relative 'puma/json_serialization'
|
17
|
-
require_relative 'rack/version_restriction'
|
18
18
|
|
19
19
|
module Puma
|
20
|
-
|
21
|
-
|
22
|
-
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"
|
23
26
|
|
24
27
|
# at present, MiniSSL::Engine is only defined in extension code (puma_http11),
|
25
28
|
# not in minissl.rb
|
26
29
|
HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
|
27
30
|
|
28
|
-
HAS_UNIX_SOCKET = Object.const_defined?
|
31
|
+
HAS_UNIX_SOCKET = Object.const_defined? :UNIXSocket
|
29
32
|
|
30
33
|
if HAS_SSL
|
31
|
-
|
34
|
+
require_relative 'puma/minissl'
|
32
35
|
else
|
33
36
|
module MiniSSL
|
34
37
|
# this class is defined so that it exists when Puma is compiled
|
@@ -71,9 +74,7 @@ module Puma
|
|
71
74
|
@get_stats.stats
|
72
75
|
end
|
73
76
|
|
74
|
-
# Thread name is new in Ruby 2.3
|
75
77
|
def self.set_thread_name(name)
|
76
|
-
return unless Thread.current.respond_to?(:name=)
|
77
78
|
Thread.current.name = "puma #{name}"
|
78
79
|
end
|
79
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
File without changes
|
data/tools/trickletest.rb
CHANGED
File without changes
|