puma 6.6.1-java → 7.0.0-java
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.
- checksums.yaml +4 -4
- data/History.md +89 -4
- data/README.md +11 -24
- data/docs/fork_worker.md +5 -5
- data/docs/kubernetes.md +6 -4
- data/docs/restart.md +2 -2
- data/docs/signals.md +9 -9
- data/docs/stats.md +2 -1
- data/ext/puma_http11/extconf.rb +2 -17
- data/ext/puma_http11/mini_ssl.c +0 -5
- data/lib/puma/binder.rb +10 -8
- data/lib/puma/cli.rb +3 -5
- data/lib/puma/client.rb +31 -31
- data/lib/puma/cluster/worker.rb +9 -10
- data/lib/puma/cluster/worker_handle.rb +34 -5
- data/lib/puma/cluster.rb +12 -13
- data/lib/puma/commonlogger.rb +3 -3
- data/lib/puma/configuration.rb +86 -43
- data/lib/puma/const.rb +9 -10
- data/lib/puma/control_cli.rb +3 -2
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +108 -81
- data/lib/puma/error_logger.rb +3 -1
- data/lib/puma/events.rb +13 -13
- data/lib/puma/io_buffer.rb +8 -4
- data/lib/puma/launcher/bundle_pruner.rb +1 -1
- data/lib/puma/launcher.rb +28 -29
- data/lib/puma/minissl.rb +0 -1
- data/lib/puma/plugin/systemd.rb +3 -3
- data/lib/puma/rack/urlmap.rb +1 -1
- data/lib/puma/reactor.rb +19 -4
- data/lib/puma/request.rb +26 -23
- data/lib/puma/runner.rb +8 -17
- data/lib/puma/server.rb +80 -48
- data/lib/puma/single.rb +4 -1
- data/lib/puma/thread_pool.rb +27 -81
- data/lib/puma/util.rb +0 -7
- data/lib/puma.rb +10 -0
- data/lib/rack/handler/puma.rb +2 -2
- metadata +4 -4
data/lib/puma/reactor.rb
CHANGED
@@ -15,6 +15,12 @@ module Puma
|
|
15
15
|
#
|
16
16
|
# The implementation uses a Queue to synchronize adding new objects from the internal select loop.
|
17
17
|
class Reactor
|
18
|
+
|
19
|
+
# @!attribute [rw] reactor_max
|
20
|
+
# Maximum number of clients in the selector. Reset with calls to `Server.stats`.
|
21
|
+
attr_accessor :reactor_max
|
22
|
+
attr_reader :reactor_size
|
23
|
+
|
18
24
|
# Create a new Reactor to monitor IO objects added by #add.
|
19
25
|
# The provided block will be invoked when an IO has data available to read,
|
20
26
|
# its timeout elapses, or when the Reactor shuts down.
|
@@ -29,6 +35,8 @@ module Puma
|
|
29
35
|
@input = Queue.new
|
30
36
|
@timeouts = []
|
31
37
|
@block = block
|
38
|
+
@reactor_size = 0
|
39
|
+
@reactor_max = 0
|
32
40
|
end
|
33
41
|
|
34
42
|
# Run the internal select loop, using a background thread by default.
|
@@ -73,11 +81,15 @@ module Puma
|
|
73
81
|
# Wakeup any registered object that receives incoming data.
|
74
82
|
# Block until the earliest timeout or Selector#wakeup is called.
|
75
83
|
timeout = (earliest = @timeouts.first) && earliest.timeout
|
76
|
-
|
84
|
+
monitor_wake_up = false
|
85
|
+
@selector.select(timeout) do |monitor|
|
86
|
+
monitor_wake_up = true
|
87
|
+
wakeup!(monitor.value)
|
88
|
+
end
|
77
89
|
|
78
90
|
# Wakeup all objects that timed out.
|
79
|
-
timed_out = @timeouts.take_while {|
|
80
|
-
timed_out.each { |
|
91
|
+
timed_out = @timeouts.take_while { |client| client.timeout == 0 }
|
92
|
+
timed_out.each { |client| wakeup!(client) }
|
81
93
|
|
82
94
|
unless @input.empty?
|
83
95
|
until @input.empty?
|
@@ -94,7 +106,7 @@ module Puma
|
|
94
106
|
# NoMethodError may be rarely raised when calling @selector.select, which
|
95
107
|
# is odd. Regardless, it may continue for thousands of calls if retried.
|
96
108
|
# Also, when it raises, @selector.close also raises an error.
|
97
|
-
if NoMethodError === e
|
109
|
+
if !monitor_wake_up && NoMethodError === e
|
98
110
|
close_selector = false
|
99
111
|
else
|
100
112
|
retry
|
@@ -108,6 +120,8 @@ module Puma
|
|
108
120
|
# Start monitoring the object.
|
109
121
|
def register(client)
|
110
122
|
@selector.register(client.to_io, :r).value = client
|
123
|
+
@reactor_size += 1
|
124
|
+
@reactor_max = @reactor_size if @reactor_max < @reactor_size
|
111
125
|
@timeouts << client
|
112
126
|
rescue ArgumentError
|
113
127
|
# unreadable clients raise error when processed by NIO
|
@@ -118,6 +132,7 @@ module Puma
|
|
118
132
|
def wakeup!(client)
|
119
133
|
if @block.call client
|
120
134
|
@selector.deregister client.to_io
|
135
|
+
@reactor_size -= 1
|
121
136
|
@timeouts.delete client
|
122
137
|
end
|
123
138
|
end
|
data/lib/puma/request.rb
CHANGED
@@ -52,6 +52,7 @@ module Puma
|
|
52
52
|
io_buffer = client.io_buffer
|
53
53
|
socket = client.io # io may be a MiniSSL::Socket
|
54
54
|
app_body = nil
|
55
|
+
error = nil
|
55
56
|
|
56
57
|
return false if closed_socket?(socket)
|
57
58
|
|
@@ -68,7 +69,7 @@ module Puma
|
|
68
69
|
end
|
69
70
|
|
70
71
|
env[HIJACK_P] = true
|
71
|
-
env[HIJACK] = client
|
72
|
+
env[HIJACK] = client.method :full_hijack
|
72
73
|
|
73
74
|
env[RACK_INPUT] = client.body
|
74
75
|
env[RACK_URL_SCHEME] ||= default_server_port(env) == PORT_443 ? HTTPS : HTTP
|
@@ -92,6 +93,7 @@ module Puma
|
|
92
93
|
# array, we will invoke them when the request is done.
|
93
94
|
#
|
94
95
|
env[RACK_AFTER_REPLY] ||= []
|
96
|
+
env[RACK_RESPONSE_FINISHED] ||= []
|
95
97
|
|
96
98
|
begin
|
97
99
|
if @supported_http_methods == :any || @supported_http_methods.key?(env[REQUEST_METHOD])
|
@@ -119,15 +121,15 @@ module Puma
|
|
119
121
|
|
120
122
|
return :async
|
121
123
|
end
|
122
|
-
rescue ThreadPool::ForceShutdown =>
|
123
|
-
@log_writer.unknown_error
|
124
|
+
rescue ThreadPool::ForceShutdown => error
|
125
|
+
@log_writer.unknown_error error, client, "Rack app"
|
124
126
|
@log_writer.log "Detected force shutdown of a thread"
|
125
127
|
|
126
|
-
status, headers, res_body = lowlevel_error(
|
127
|
-
rescue Exception =>
|
128
|
-
@log_writer.unknown_error
|
128
|
+
status, headers, res_body = lowlevel_error(error, env, 503)
|
129
|
+
rescue Exception => error
|
130
|
+
@log_writer.unknown_error error, client, "Rack app"
|
129
131
|
|
130
|
-
status, headers, res_body = lowlevel_error(
|
132
|
+
status, headers, res_body = lowlevel_error(error, env, 500)
|
131
133
|
end
|
132
134
|
prepare_response(status, headers, res_body, requests, client)
|
133
135
|
ensure
|
@@ -144,6 +146,16 @@ module Puma
|
|
144
146
|
end
|
145
147
|
end
|
146
148
|
end
|
149
|
+
|
150
|
+
if response_finished = env[RACK_RESPONSE_FINISHED]
|
151
|
+
response_finished.reverse_each do |o|
|
152
|
+
begin
|
153
|
+
o.call(env, status, headers, error)
|
154
|
+
rescue StandardError => e
|
155
|
+
@log_writer.debug_error e
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
147
159
|
end
|
148
160
|
|
149
161
|
# Assembles the headers and prepares the body for actually sending the
|
@@ -164,17 +176,7 @@ module Puma
|
|
164
176
|
return false if closed_socket?(socket)
|
165
177
|
|
166
178
|
# Close the connection after a reasonable number of inline requests
|
167
|
-
|
168
|
-
# This allows Puma to service connections fairly when the number
|
169
|
-
# of concurrent connections exceeds the size of the threadpool.
|
170
|
-
force_keep_alive = if @enable_keep_alives
|
171
|
-
requests < @max_fast_inline ||
|
172
|
-
@thread_pool.busy_threads < @max_threads ||
|
173
|
-
!client.listener.to_io.wait_readable(0)
|
174
|
-
else
|
175
|
-
# Always set force_keep_alive to false if the server has keep-alives not enabled.
|
176
|
-
false
|
177
|
-
end
|
179
|
+
force_keep_alive = @enable_keep_alives && client.requests_served < @max_keep_alive
|
178
180
|
|
179
181
|
resp_info = str_headers(env, status, headers, res_body, io_buffer, force_keep_alive)
|
180
182
|
|
@@ -267,7 +269,8 @@ module Puma
|
|
267
269
|
|
268
270
|
fast_write_response socket, body, io_buffer, chunked, content_length.to_i
|
269
271
|
body.close if close_body
|
270
|
-
keep_alive
|
272
|
+
# if we're shutting down, close keep_alive connections
|
273
|
+
!shutting_down? && keep_alive
|
271
274
|
end
|
272
275
|
|
273
276
|
# @param env [Hash] see Puma::Client#env, from request
|
@@ -478,7 +481,7 @@ module Puma
|
|
478
481
|
|
479
482
|
# The legacy HTTP_VERSION header can be sent as a client header.
|
480
483
|
# Rack v4 may remove using HTTP_VERSION. If so, remove this line.
|
481
|
-
env[HTTP_VERSION] = env[SERVER_PROTOCOL]
|
484
|
+
env[HTTP_VERSION] = env[SERVER_PROTOCOL] if @env_set_http_version
|
482
485
|
end
|
483
486
|
private :normalize_env
|
484
487
|
|
@@ -585,7 +588,7 @@ module Puma
|
|
585
588
|
# response body
|
586
589
|
# @param io_buffer [Puma::IOBuffer] modified inn place
|
587
590
|
# @param force_keep_alive [Boolean] 'anded' with keep_alive, based on system
|
588
|
-
# status and `@
|
591
|
+
# status and `@max_keep_alive`
|
589
592
|
# @return [Hash] resp_info
|
590
593
|
# @version 5.0.3
|
591
594
|
#
|
@@ -668,10 +671,10 @@ module Puma
|
|
668
671
|
if ary
|
669
672
|
ary.each do |v|
|
670
673
|
next if illegal_header_value?(v)
|
671
|
-
io_buffer.append k, colon, v, line_ending
|
674
|
+
io_buffer.append k.downcase, colon, v, line_ending
|
672
675
|
end
|
673
676
|
else
|
674
|
-
io_buffer.append k, colon, line_ending
|
677
|
+
io_buffer.append k.downcase, colon, line_ending
|
675
678
|
end
|
676
679
|
end
|
677
680
|
|
data/lib/puma/runner.rb
CHANGED
@@ -33,7 +33,6 @@ module Puma
|
|
33
33
|
@wakeup.write PIPE_WAKEUP unless @wakeup.closed?
|
34
34
|
|
35
35
|
rescue SystemCallError, IOError
|
36
|
-
Puma::Util.purge_interrupt_queue
|
37
36
|
end
|
38
37
|
|
39
38
|
def development?
|
@@ -93,22 +92,6 @@ module Puma
|
|
93
92
|
@control.binder.close_listeners if @control
|
94
93
|
end
|
95
94
|
|
96
|
-
# @!attribute [r] ruby_engine
|
97
|
-
# @deprecated Use `RUBY_DESCRIPTION` instead
|
98
|
-
def ruby_engine
|
99
|
-
warn "Puma::Runner#ruby_engine is deprecated; use RUBY_DESCRIPTION instead. It will be removed in puma v7."
|
100
|
-
|
101
|
-
if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby"
|
102
|
-
"ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
|
103
|
-
else
|
104
|
-
if defined?(RUBY_ENGINE_VERSION)
|
105
|
-
"#{RUBY_ENGINE} #{RUBY_ENGINE_VERSION} - ruby #{RUBY_VERSION}"
|
106
|
-
else
|
107
|
-
"#{RUBY_ENGINE} #{RUBY_VERSION}"
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
95
|
def output_header(mode)
|
113
96
|
min_t = @options[:min_threads]
|
114
97
|
max_t = @options[:max_threads]
|
@@ -128,6 +111,14 @@ module Puma
|
|
128
111
|
end
|
129
112
|
end
|
130
113
|
|
114
|
+
def warn_ruby_mn_threads
|
115
|
+
return if !ENV.key?('RUBY_MN_THREADS')
|
116
|
+
|
117
|
+
log "! WARNING: Detected `RUBY_MN_THREADS=#{ENV['RUBY_MN_THREADS']}`"
|
118
|
+
log "! This setting is known to cause performance regressions with Puma."
|
119
|
+
log "! Consider disabling this environment variable: https://github.com/puma/puma/issues/3720"
|
120
|
+
end
|
121
|
+
|
131
122
|
def redirected_io?
|
132
123
|
@options[:redirect_stdout] || @options[:redirect_stderr]
|
133
124
|
end
|
data/lib/puma/server.rb
CHANGED
@@ -12,14 +12,14 @@ require_relative 'client'
|
|
12
12
|
require_relative 'binder'
|
13
13
|
require_relative 'util'
|
14
14
|
require_relative 'request'
|
15
|
+
require_relative 'configuration'
|
15
16
|
|
16
17
|
require 'socket'
|
17
18
|
require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT
|
18
19
|
|
19
20
|
module Puma
|
20
|
-
|
21
|
-
|
22
|
-
Thread.send(:attr_accessor, :puma_server)
|
21
|
+
# Add `Thread#puma_server` and `Thread#puma_server=`
|
22
|
+
Thread.attr_accessor(:puma_server)
|
23
23
|
|
24
24
|
# The HTTP Server itself. Serves out a single Rack app.
|
25
25
|
#
|
@@ -32,6 +32,14 @@ module Puma
|
|
32
32
|
#
|
33
33
|
# Each `Puma::Server` will have one reactor and one thread pool.
|
34
34
|
class Server
|
35
|
+
module FiberPerRequest
|
36
|
+
def handle_request(client, requests)
|
37
|
+
Fiber.new do
|
38
|
+
super
|
39
|
+
end.resume
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
35
43
|
include Puma::Const
|
36
44
|
include Request
|
37
45
|
|
@@ -77,6 +85,9 @@ module Puma
|
|
77
85
|
|
78
86
|
@thread = nil
|
79
87
|
@thread_pool = nil
|
88
|
+
@reactor = nil
|
89
|
+
|
90
|
+
@env_set_http_version = nil
|
80
91
|
|
81
92
|
@options = if options.is_a?(UserFileDefaultOptions)
|
82
93
|
options
|
@@ -94,11 +105,16 @@ module Puma
|
|
94
105
|
@min_threads = @options[:min_threads]
|
95
106
|
@max_threads = @options[:max_threads]
|
96
107
|
@queue_requests = @options[:queue_requests]
|
97
|
-
@
|
108
|
+
@max_keep_alive = @options[:max_keep_alive]
|
98
109
|
@enable_keep_alives = @options[:enable_keep_alives]
|
110
|
+
@enable_keep_alives &&= @queue_requests
|
99
111
|
@io_selector_backend = @options[:io_selector_backend]
|
100
112
|
@http_content_length_limit = @options[:http_content_length_limit]
|
101
113
|
|
114
|
+
if @options[:fiber_per_request]
|
115
|
+
singleton_class.prepend(FiberPerRequest)
|
116
|
+
end
|
117
|
+
|
102
118
|
# make this a hash, since we prefer `key?` over `include?`
|
103
119
|
@supported_http_methods =
|
104
120
|
if @options[:supported_http_methods] == :any
|
@@ -114,7 +130,7 @@ module Puma
|
|
114
130
|
temp = !!(@options[:environment] =~ /\A(development|test)\z/)
|
115
131
|
@leak_stack_on_error = @options[:environment] ? temp : true
|
116
132
|
|
117
|
-
@binder = Binder.new(log_writer)
|
133
|
+
@binder = Binder.new(log_writer, @options)
|
118
134
|
|
119
135
|
ENV['RACK_ENV'] ||= "development"
|
120
136
|
|
@@ -165,7 +181,6 @@ module Puma
|
|
165
181
|
begin
|
166
182
|
skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 1) if skt.kind_of? TCPSocket
|
167
183
|
rescue IOError, SystemCallError
|
168
|
-
Puma::Util.purge_interrupt_queue
|
169
184
|
end
|
170
185
|
end
|
171
186
|
|
@@ -174,7 +189,6 @@ module Puma
|
|
174
189
|
begin
|
175
190
|
skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 0) if skt.kind_of? TCPSocket
|
176
191
|
rescue IOError, SystemCallError
|
177
|
-
Puma::Util.purge_interrupt_queue
|
178
192
|
end
|
179
193
|
end
|
180
194
|
else
|
@@ -195,7 +209,6 @@ module Puma
|
|
195
209
|
begin
|
196
210
|
tcp_info = skt.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_INFO)
|
197
211
|
rescue IOError, SystemCallError
|
198
|
-
Puma::Util.purge_interrupt_queue
|
199
212
|
@precheck_closing = false
|
200
213
|
false
|
201
214
|
else
|
@@ -220,7 +233,6 @@ module Puma
|
|
220
233
|
@thread_pool&.spawned
|
221
234
|
end
|
222
235
|
|
223
|
-
|
224
236
|
# This number represents the number of requests that
|
225
237
|
# the server is capable of taking right now.
|
226
238
|
#
|
@@ -318,12 +330,16 @@ module Puma
|
|
318
330
|
end
|
319
331
|
|
320
332
|
def handle_servers
|
333
|
+
@env_set_http_version = Object.const_defined?(:Rack) && ::Rack.respond_to?(:release) &&
|
334
|
+
Gem::Version.new(::Rack.release) < Gem::Version.new('3.1.0')
|
335
|
+
|
321
336
|
begin
|
322
337
|
check = @check
|
323
338
|
sockets = [check] + @binder.ios
|
324
339
|
pool = @thread_pool
|
325
340
|
queue_requests = @queue_requests
|
326
341
|
drain = options[:drain_on_shutdown] ? 0 : nil
|
342
|
+
max_flt = @max_threads.to_f
|
327
343
|
|
328
344
|
addr_send_name, addr_value = case options[:remote_address]
|
329
345
|
when :value
|
@@ -364,8 +380,20 @@ module Puma
|
|
364
380
|
if sock == check
|
365
381
|
break if handle_check
|
366
382
|
else
|
367
|
-
|
368
|
-
|
383
|
+
# if ThreadPool out_of_band code is running, we don't want to add
|
384
|
+
# clients until the code is finished.
|
385
|
+
sleep 0.001 while pool.out_of_band_running
|
386
|
+
|
387
|
+
# only use delay when clustered and busy
|
388
|
+
if pool.busy_threads >= @max_threads
|
389
|
+
if @clustered
|
390
|
+
delay = 0.0001 * ((@reactor&.reactor_size || 0) + pool.busy_threads * 1.5)/max_flt
|
391
|
+
sleep delay
|
392
|
+
else
|
393
|
+
# use small sleep for busy single worker
|
394
|
+
sleep 0.0001
|
395
|
+
end
|
396
|
+
end
|
369
397
|
|
370
398
|
io = begin
|
371
399
|
sock.accept_nonblock
|
@@ -447,14 +475,12 @@ module Puma
|
|
447
475
|
# Advertise this server into the thread
|
448
476
|
Thread.current.puma_server = self
|
449
477
|
|
450
|
-
clean_thread_locals = options[:clean_thread_locals]
|
451
478
|
close_socket = true
|
452
479
|
|
453
480
|
requests = 0
|
454
481
|
|
455
482
|
begin
|
456
|
-
if @queue_requests &&
|
457
|
-
!client.eagerly_finish
|
483
|
+
if @queue_requests && !client.eagerly_finish
|
458
484
|
|
459
485
|
client.set_timeout(@first_data_timeout)
|
460
486
|
if @reactor.add client
|
@@ -467,39 +493,31 @@ module Puma
|
|
467
493
|
client.finish(@first_data_timeout)
|
468
494
|
end
|
469
495
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
break
|
478
|
-
when true
|
479
|
-
ThreadPool.clean_thread_locals if clean_thread_locals
|
480
|
-
|
481
|
-
requests += 1
|
482
|
-
|
483
|
-
# As an optimization, try to read the next request from the
|
484
|
-
# socket for a short time before returning to the reactor.
|
485
|
-
fast_check = @status == :run
|
496
|
+
@requests_count += 1
|
497
|
+
case handle_request(client, requests + 1)
|
498
|
+
when false
|
499
|
+
when :async
|
500
|
+
close_socket = false
|
501
|
+
when true
|
502
|
+
requests += 1
|
486
503
|
|
487
|
-
|
488
|
-
# number of inline requests if there are other requests pending.
|
489
|
-
fast_check = false if requests >= @max_fast_inline &&
|
490
|
-
@thread_pool.backlog > 0
|
504
|
+
client.reset
|
491
505
|
|
492
|
-
|
493
|
-
|
494
|
-
|
506
|
+
# This indicates data exists in the client read buffer and there may be
|
507
|
+
# additional requests on it, so process them
|
508
|
+
next_request_ready = if client.has_back_to_back_requests?
|
509
|
+
with_force_shutdown(client) { client.process_back_to_back_requests }
|
510
|
+
else
|
511
|
+
nil
|
512
|
+
end
|
495
513
|
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
514
|
+
if next_request_ready
|
515
|
+
@thread_pool << client
|
516
|
+
close_socket = false
|
517
|
+
elsif @queue_requests
|
518
|
+
client.set_timeout @persistent_timeout
|
519
|
+
if @reactor.add client
|
520
|
+
close_socket = false
|
503
521
|
end
|
504
522
|
end
|
505
523
|
end
|
@@ -514,7 +532,6 @@ module Puma
|
|
514
532
|
begin
|
515
533
|
client.close if close_socket
|
516
534
|
rescue IOError, SystemCallError
|
517
|
-
Puma::Util.purge_interrupt_queue
|
518
535
|
# Already closed
|
519
536
|
rescue StandardError => e
|
520
537
|
@log_writer.unknown_error e, nil, "Client"
|
@@ -615,11 +632,10 @@ module Puma
|
|
615
632
|
@notify << message
|
616
633
|
rescue IOError, NoMethodError, Errno::EPIPE, Errno::EBADF
|
617
634
|
# The server, in another thread, is shutting down
|
618
|
-
Puma::Util.purge_interrupt_queue
|
619
635
|
rescue RuntimeError => e
|
620
636
|
# Temporary workaround for https://bugs.ruby-lang.org/issues/13239
|
621
637
|
if e.message.include?('IOError')
|
622
|
-
|
638
|
+
# ignore
|
623
639
|
else
|
624
640
|
raise e
|
625
641
|
end
|
@@ -650,7 +666,16 @@ module Puma
|
|
650
666
|
|
651
667
|
# List of methods invoked by #stats.
|
652
668
|
# @version 5.0.0
|
653
|
-
STAT_METHODS = [
|
669
|
+
STAT_METHODS = [
|
670
|
+
:backlog,
|
671
|
+
:running,
|
672
|
+
:pool_capacity,
|
673
|
+
:busy_threads,
|
674
|
+
:backlog_max,
|
675
|
+
:max_threads,
|
676
|
+
:requests_count,
|
677
|
+
:reactor_max,
|
678
|
+
].freeze
|
654
679
|
|
655
680
|
# Returns a hash of stats about the running server for reporting purposes.
|
656
681
|
# @version 5.0.0
|
@@ -660,9 +685,16 @@ module Puma
|
|
660
685
|
stats = @thread_pool&.stats || {}
|
661
686
|
stats[:max_threads] = @max_threads
|
662
687
|
stats[:requests_count] = @requests_count
|
688
|
+
stats[:reactor_max] = @reactor.reactor_max
|
689
|
+
reset_max
|
663
690
|
stats
|
664
691
|
end
|
665
692
|
|
693
|
+
def reset_max
|
694
|
+
@reactor.reactor_max = 0
|
695
|
+
@thread_pool.reset_max
|
696
|
+
end
|
697
|
+
|
666
698
|
# below are 'delegations' to binder
|
667
699
|
# remove in Puma 7?
|
668
700
|
|
data/lib/puma/single.rb
CHANGED
@@ -53,9 +53,12 @@ module Puma
|
|
53
53
|
server_thread = server.run
|
54
54
|
|
55
55
|
log "Use Ctrl-C to stop"
|
56
|
+
|
57
|
+
warn_ruby_mn_threads
|
58
|
+
|
56
59
|
redirect_io
|
57
60
|
|
58
|
-
@events.
|
61
|
+
@events.fire_after_booted!
|
59
62
|
|
60
63
|
debug_loaded_extensions("Loaded Extensions:") if @log_writer.debug?
|
61
64
|
|