puma 5.6.5-java → 6.0.1-java
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 +120 -11
- data/README.md +21 -17
- data/bin/puma-wild +1 -1
- data/docs/compile_options.md +34 -0
- data/docs/fork_worker.md +1 -3
- data/docs/nginx.md +1 -1
- 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 +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/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 +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 +26 -13
- 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/configuration.rb +74 -58
- data/lib/puma/const.rb +14 -18
- data/lib/puma/control_cli.rb +3 -6
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +96 -52
- data/lib/puma/error_logger.rb +17 -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 +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/plugin/tmp_restart.rb +1 -1
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/rack/builder.rb +4 -4
- data/lib/puma/rack_default.rb +1 -1
- data/lib/puma/reactor.rb +4 -4
- data/lib/puma/request.rb +334 -166
- data/lib/puma/runner.rb +41 -20
- data/lib/puma/server.rb +55 -71
- 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 -16
- data/lib/puma/util.rb +0 -11
- data/lib/puma.rb +12 -9
- data/lib/rack/handler/puma.rb +9 -9
- metadata +8 -4
- data/lib/puma/queue_close.rb +0 -26
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,19 @@
|
|
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 'request'
|
15
15
|
|
16
16
|
require 'socket'
|
17
|
-
require 'io/wait'
|
17
|
+
require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT
|
18
18
|
require 'forwardable'
|
19
19
|
|
20
20
|
module Puma
|
@@ -30,27 +30,21 @@ module Puma
|
|
30
30
|
#
|
31
31
|
# Each `Puma::Server` will have one reactor and one thread pool.
|
32
32
|
class Server
|
33
|
-
|
34
33
|
include Puma::Const
|
35
34
|
include Request
|
36
35
|
extend Forwardable
|
37
36
|
|
38
37
|
attr_reader :thread
|
38
|
+
attr_reader :log_writer
|
39
39
|
attr_reader :events
|
40
40
|
attr_reader :min_threads, :max_threads # for #stats
|
41
41
|
attr_reader :requests_count # @version 5.0.0
|
42
|
-
attr_reader :log_writer # to help with backports
|
43
42
|
|
44
43
|
# @todo the following may be deprecated in the future
|
45
44
|
attr_reader :auto_trim_time, :early_hints, :first_data_timeout,
|
46
45
|
:leak_stack_on_error,
|
47
46
|
:persistent_timeout, :reaping_time
|
48
47
|
|
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
48
|
attr_accessor :app
|
55
49
|
attr_accessor :binder
|
56
50
|
|
@@ -61,8 +55,9 @@ module Puma
|
|
61
55
|
|
62
56
|
# Create a server for the rack app +app+.
|
63
57
|
#
|
64
|
-
# +
|
65
|
-
#
|
58
|
+
# +log_writer+ is a Puma::LogWriter object used to log info and error messages.
|
59
|
+
#
|
60
|
+
# +events+ is a Puma::Events object used to notify application status events.
|
66
61
|
#
|
67
62
|
# Server#run returns a thread that you can join on to wait for the server
|
68
63
|
# to do its work.
|
@@ -71,35 +66,40 @@ module Puma
|
|
71
66
|
# and have default values set via +fetch+. Normally the values are set via
|
72
67
|
# `::Puma::Configuration.puma_default_options`.
|
73
68
|
#
|
74
|
-
|
69
|
+
# @note The `events` parameter is set to nil, and set to `Events.new` in code.
|
70
|
+
# Often `options` needs to be passed, but `events` does not. Using nil allows
|
71
|
+
# calling code to not require events.rb.
|
72
|
+
#
|
73
|
+
def initialize(app, events = nil, options = {})
|
75
74
|
@app = app
|
76
|
-
@events = events
|
77
|
-
@log_writer = events
|
75
|
+
@events = events || Events.new
|
78
76
|
|
79
77
|
@check, @notify = nil
|
80
78
|
@status = :stop
|
81
79
|
|
82
|
-
@auto_trim_time = 30
|
83
|
-
@reaping_time = 1
|
84
|
-
|
85
80
|
@thread = nil
|
86
81
|
@thread_pool = nil
|
87
82
|
|
88
|
-
@options = options
|
83
|
+
@options = if options.is_a?(UserFileDefaultOptions)
|
84
|
+
options
|
85
|
+
else
|
86
|
+
UserFileDefaultOptions.new(options, Configuration::DEFAULTS)
|
87
|
+
end
|
89
88
|
|
90
|
-
@
|
91
|
-
@
|
92
|
-
@
|
93
|
-
@
|
94
|
-
@
|
95
|
-
@
|
96
|
-
@
|
97
|
-
@
|
89
|
+
@log_writer = @options.fetch :log_writer, LogWriter.stdio
|
90
|
+
@early_hints = @options[:early_hints]
|
91
|
+
@first_data_timeout = @options[:first_data_timeout]
|
92
|
+
@min_threads = @options[:min_threads]
|
93
|
+
@max_threads = @options[:max_threads]
|
94
|
+
@persistent_timeout = @options[:persistent_timeout]
|
95
|
+
@queue_requests = @options[:queue_requests]
|
96
|
+
@max_fast_inline = @options[:max_fast_inline]
|
97
|
+
@io_selector_backend = @options[:io_selector_backend]
|
98
98
|
|
99
99
|
temp = !!(@options[:environment] =~ /\A(development|test)\z/)
|
100
100
|
@leak_stack_on_error = @options[:environment] ? temp : true
|
101
101
|
|
102
|
-
@binder = Binder.new(
|
102
|
+
@binder = Binder.new(log_writer)
|
103
103
|
|
104
104
|
ENV['RACK_ENV'] ||= "development"
|
105
105
|
|
@@ -195,12 +195,12 @@ module Puma
|
|
195
195
|
|
196
196
|
# @!attribute [r] backlog
|
197
197
|
def backlog
|
198
|
-
@thread_pool
|
198
|
+
@thread_pool&.backlog
|
199
199
|
end
|
200
200
|
|
201
201
|
# @!attribute [r] running
|
202
202
|
def running
|
203
|
-
@thread_pool
|
203
|
+
@thread_pool&.spawned
|
204
204
|
end
|
205
205
|
|
206
206
|
|
@@ -213,7 +213,7 @@ module Puma
|
|
213
213
|
# value would be 4 until it finishes processing.
|
214
214
|
# @!attribute [r] pool_capacity
|
215
215
|
def pool_capacity
|
216
|
-
@thread_pool
|
216
|
+
@thread_pool&.pool_capacity
|
217
217
|
end
|
218
218
|
|
219
219
|
# Runs the server.
|
@@ -229,29 +229,16 @@ module Puma
|
|
229
229
|
|
230
230
|
@status = :run
|
231
231
|
|
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]
|
232
|
+
@thread_pool = ThreadPool.new(thread_name, @options) { |client| process_client client }
|
242
233
|
|
243
234
|
if @queue_requests
|
244
|
-
@reactor = Reactor.new(@io_selector_backend
|
235
|
+
@reactor = Reactor.new(@io_selector_backend) { |c| reactor_wakeup c }
|
245
236
|
@reactor.run
|
246
237
|
end
|
247
238
|
|
248
|
-
if @reaping_time
|
249
|
-
@thread_pool.auto_reap!(@reaping_time)
|
250
|
-
end
|
251
239
|
|
252
|
-
if @
|
253
|
-
|
254
|
-
end
|
240
|
+
@thread_pool.auto_reap! if @options[:reaping_time]
|
241
|
+
@thread_pool.auto_trim! if @options[:auto_trim_time]
|
255
242
|
|
256
243
|
@check, @notify = Puma::Util.pipe unless @notify
|
257
244
|
|
@@ -355,11 +342,11 @@ module Puma
|
|
355
342
|
# In the case that any of the sockets are unexpectedly close.
|
356
343
|
raise
|
357
344
|
rescue StandardError => e
|
358
|
-
@
|
345
|
+
@log_writer.unknown_error e, nil, "Listen loop"
|
359
346
|
end
|
360
347
|
end
|
361
348
|
|
362
|
-
@
|
349
|
+
@log_writer.debug "Drained #{drain} additional connections." if drain
|
363
350
|
@events.fire :state, @status
|
364
351
|
|
365
352
|
if queue_requests
|
@@ -368,14 +355,13 @@ module Puma
|
|
368
355
|
end
|
369
356
|
graceful_shutdown if @status == :stop || @status == :restart
|
370
357
|
rescue Exception => e
|
371
|
-
@
|
358
|
+
@log_writer.unknown_error e, nil, "Exception handling servers"
|
372
359
|
ensure
|
373
|
-
# RuntimeError is Ruby 2.2 issue, can't modify frozen IOError
|
374
360
|
# Errno::EBADF is infrequently raised
|
375
361
|
[@check, @notify].each do |io|
|
376
362
|
begin
|
377
363
|
io.close unless io.closed?
|
378
|
-
rescue Errno::EBADF
|
364
|
+
rescue Errno::EBADF
|
379
365
|
end
|
380
366
|
end
|
381
367
|
@notify = nil
|
@@ -414,7 +400,7 @@ module Puma
|
|
414
400
|
# returning.
|
415
401
|
#
|
416
402
|
# Return true if one or more requests were processed.
|
417
|
-
def process_client(client
|
403
|
+
def process_client(client)
|
418
404
|
# Advertise this server into the thread
|
419
405
|
Thread.current[ThreadLocalKey] = self
|
420
406
|
|
@@ -440,15 +426,13 @@ module Puma
|
|
440
426
|
|
441
427
|
while true
|
442
428
|
@requests_count += 1
|
443
|
-
case handle_request(client,
|
429
|
+
case handle_request(client, requests + 1)
|
444
430
|
when false
|
445
431
|
break
|
446
432
|
when :async
|
447
433
|
close_socket = false
|
448
434
|
break
|
449
435
|
when true
|
450
|
-
buffer.reset
|
451
|
-
|
452
436
|
ThreadPool.clean_thread_locals if clean_thread_locals
|
453
437
|
|
454
438
|
requests += 1
|
@@ -482,7 +466,7 @@ module Puma
|
|
482
466
|
# The ensure tries to close +client+ down
|
483
467
|
requests > 0
|
484
468
|
ensure
|
485
|
-
|
469
|
+
client.io_buffer.reset
|
486
470
|
|
487
471
|
begin
|
488
472
|
client.close if close_socket
|
@@ -490,7 +474,7 @@ module Puma
|
|
490
474
|
Puma::Util.purge_interrupt_queue
|
491
475
|
# Already closed
|
492
476
|
rescue StandardError => e
|
493
|
-
@
|
477
|
+
@log_writer.unknown_error e, nil, "Client"
|
494
478
|
end
|
495
479
|
end
|
496
480
|
end
|
@@ -513,16 +497,16 @@ module Puma
|
|
513
497
|
lowlevel_error(e, client.env)
|
514
498
|
case e
|
515
499
|
when MiniSSL::SSLError
|
516
|
-
@
|
500
|
+
@log_writer.ssl_error e, client.io
|
517
501
|
when HttpParserError
|
518
502
|
client.write_error(400)
|
519
|
-
@
|
503
|
+
@log_writer.parse_error e, client
|
520
504
|
when HttpParserError501
|
521
505
|
client.write_error(501)
|
522
|
-
@
|
506
|
+
@log_writer.parse_error e, client
|
523
507
|
else
|
524
508
|
client.write_error(500)
|
525
|
-
@
|
509
|
+
@log_writer.unknown_error e, nil, "Read"
|
526
510
|
end
|
527
511
|
end
|
528
512
|
|
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,13 @@ 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
|
-
@
|
48
|
+
@out_of_band = options[:out_of_band]
|
49
|
+
@clean_thread_locals = options[:clean_thread_locals]
|
50
|
+
@reaping_time = options[:reaping_time]
|
51
|
+
@auto_trim_time = options[:auto_trim_time]
|
47
52
|
|
48
53
|
@shutdown = false
|
49
54
|
|
@@ -62,14 +67,11 @@ module Puma
|
|
62
67
|
end
|
63
68
|
end
|
64
69
|
|
65
|
-
@clean_thread_locals = false
|
66
70
|
@force_shutdown = false
|
67
71
|
@shutdown_mutex = Mutex.new
|
68
72
|
end
|
69
73
|
|
70
74
|
attr_reader :spawned, :trim_requested, :waiting
|
71
|
-
attr_accessor :clean_thread_locals
|
72
|
-
attr_accessor :out_of_band_hook # @version 5.0.0
|
73
75
|
|
74
76
|
def self.clean_thread_locals
|
75
77
|
Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods
|
@@ -109,8 +111,6 @@ module Puma
|
|
109
111
|
not_empty = @not_empty
|
110
112
|
not_full = @not_full
|
111
113
|
|
112
|
-
extra = @extra.map { |i| i.new }
|
113
|
-
|
114
114
|
while true
|
115
115
|
work = nil
|
116
116
|
|
@@ -144,7 +144,7 @@ module Puma
|
|
144
144
|
end
|
145
145
|
|
146
146
|
begin
|
147
|
-
@out_of_band_pending = true if block.call(work
|
147
|
+
@out_of_band_pending = true if block.call(work)
|
148
148
|
rescue Exception => e
|
149
149
|
STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})"
|
150
150
|
end
|
@@ -160,12 +160,12 @@ module Puma
|
|
160
160
|
|
161
161
|
# @version 5.0.0
|
162
162
|
def trigger_out_of_band_hook
|
163
|
-
return false unless
|
163
|
+
return false unless @out_of_band&.any?
|
164
164
|
|
165
165
|
# we execute on idle hook when all threads are free
|
166
166
|
return false unless @spawned == @waiting
|
167
167
|
|
168
|
-
|
168
|
+
@out_of_band.each(&:call)
|
169
169
|
true
|
170
170
|
rescue Exception => e
|
171
171
|
STDERR.puts "Exception calling out_of_band_hook: #{e.message} (#{e.class})"
|
@@ -319,12 +319,12 @@ module Puma
|
|
319
319
|
end
|
320
320
|
end
|
321
321
|
|
322
|
-
def auto_trim!(timeout
|
322
|
+
def auto_trim!(timeout=@auto_trim_time)
|
323
323
|
@auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
|
324
324
|
@auto_trim.start!
|
325
325
|
end
|
326
326
|
|
327
|
-
def auto_reap!(timeout
|
327
|
+
def auto_reap!(timeout=@reaping_time)
|
328
328
|
@reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
|
329
329
|
@reaper.start!
|
330
330
|
end
|
@@ -354,8 +354,8 @@ module Puma
|
|
354
354
|
@not_empty.broadcast
|
355
355
|
@not_full.broadcast
|
356
356
|
|
357
|
-
@auto_trim
|
358
|
-
@reaper
|
357
|
+
@auto_trim&.stop
|
358
|
+
@reaper&.stop
|
359
359
|
# dup workers so that we join them all safely
|
360
360
|
@workers.dup
|
361
361
|
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,23 +10,28 @@ 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
|
24
29
|
HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
|
25
30
|
|
26
|
-
HAS_UNIX_SOCKET = Object.const_defined?
|
31
|
+
HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS
|
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
|
@@ -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
|