puma 5.6.9-java → 6.6.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 +465 -18
- data/README.md +152 -42
- data/bin/puma-wild +1 -1
- data/docs/compile_options.md +34 -0
- data/docs/fork_worker.md +12 -4
- data/docs/java_options.md +54 -0
- data/docs/kubernetes.md +12 -0
- data/docs/nginx.md +1 -1
- data/docs/plugins.md +4 -0
- data/docs/restart.md +1 -0
- data/docs/signals.md +2 -2
- data/docs/stats.md +8 -3
- data/docs/systemd.md +13 -7
- 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 +27 -17
- 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 +137 -19
- data/ext/puma_http11/org/jruby/puma/Http11.java +31 -10
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +157 -53
- data/ext/puma_http11/puma_http11.c +21 -10
- data/lib/puma/app/status.rb +4 -4
- data/lib/puma/binder.rb +60 -55
- data/lib/puma/cli.rb +22 -20
- data/lib/puma/client.rb +93 -30
- data/lib/puma/cluster/worker.rb +27 -17
- data/lib/puma/cluster/worker_handle.rb +8 -6
- data/lib/puma/cluster.rb +121 -47
- data/lib/puma/commonlogger.rb +21 -14
- data/lib/puma/configuration.rb +101 -65
- data/lib/puma/const.rb +141 -93
- data/lib/puma/control_cli.rb +19 -15
- data/lib/puma/detect.rb +7 -4
- data/lib/puma/dsl.rb +521 -88
- data/lib/puma/error_logger.rb +22 -13
- data/lib/puma/events.rb +6 -126
- data/lib/puma/io_buffer.rb +39 -4
- data/lib/puma/jruby_restart.rb +0 -15
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +121 -181
- data/lib/puma/log_writer.rb +147 -0
- data/lib/puma/minissl/context_builder.rb +27 -12
- data/lib/puma/minissl.rb +105 -11
- data/lib/puma/null_io.rb +42 -2
- data/lib/puma/plugin/systemd.rb +90 -0
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/rack/builder.rb +6 -6
- data/lib/puma/rack/urlmap.rb +1 -1
- data/lib/puma/rack_default.rb +19 -4
- data/lib/puma/reactor.rb +19 -10
- data/lib/puma/request.rb +368 -169
- data/lib/puma/runner.rb +65 -22
- data/lib/puma/sd_notify.rb +146 -0
- data/lib/puma/server.rb +161 -102
- data/lib/puma/single.rb +13 -11
- data/lib/puma/state_file.rb +3 -6
- data/lib/puma/thread_pool.rb +71 -21
- data/lib/puma/util.rb +1 -12
- data/lib/puma.rb +9 -10
- data/lib/rack/handler/puma.rb +116 -86
- data/tools/Dockerfile +2 -2
- metadata +17 -12
- data/lib/puma/queue_close.rb +0 -26
- data/lib/puma/systemd.rb +0 -46
- data/lib/rack/version_restriction.rb +0 -15
data/lib/puma/server.rb
CHANGED
@@ -2,23 +2,25 @@
|
|
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'
|
18
|
-
require 'forwardable'
|
17
|
+
require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT
|
19
18
|
|
20
19
|
module Puma
|
21
20
|
|
21
|
+
# This method was private on Ruby 2.4 but became public on Ruby 2.5+:
|
22
|
+
Thread.send(:attr_accessor, :puma_server)
|
23
|
+
|
22
24
|
# The HTTP Server itself. Serves out a single Rack app.
|
23
25
|
#
|
24
26
|
# This class is used by the `Puma::Single` and `Puma::Cluster` classes
|
@@ -30,39 +32,30 @@ module Puma
|
|
30
32
|
#
|
31
33
|
# Each `Puma::Server` will have one reactor and one thread pool.
|
32
34
|
class Server
|
33
|
-
|
34
35
|
include Puma::Const
|
35
36
|
include Request
|
36
|
-
extend Forwardable
|
37
37
|
|
38
|
+
attr_reader :options
|
38
39
|
attr_reader :thread
|
40
|
+
attr_reader :log_writer
|
39
41
|
attr_reader :events
|
40
42
|
attr_reader :min_threads, :max_threads # for #stats
|
41
43
|
attr_reader :requests_count # @version 5.0.0
|
42
|
-
attr_reader :log_writer # to help with backports
|
43
44
|
|
44
45
|
# @todo the following may be deprecated in the future
|
45
46
|
attr_reader :auto_trim_time, :early_hints, :first_data_timeout,
|
46
47
|
:leak_stack_on_error,
|
47
48
|
:persistent_timeout, :reaping_time
|
48
49
|
|
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
50
|
attr_accessor :app
|
55
51
|
attr_accessor :binder
|
56
52
|
|
57
|
-
def_delegators :@binder, :add_tcp_listener, :add_ssl_listener,
|
58
|
-
:add_unix_listener, :connected_ports
|
59
|
-
|
60
|
-
ThreadLocalKey = :puma_server
|
61
53
|
|
62
54
|
# Create a server for the rack app +app+.
|
63
55
|
#
|
64
|
-
# +
|
65
|
-
#
|
56
|
+
# +log_writer+ is a Puma::LogWriter object used to log info and error messages.
|
57
|
+
#
|
58
|
+
# +events+ is a Puma::Events object used to notify application status events.
|
66
59
|
#
|
67
60
|
# Server#run returns a thread that you can join on to wait for the server
|
68
61
|
# to do its work.
|
@@ -71,35 +64,57 @@ module Puma
|
|
71
64
|
# and have default values set via +fetch+. Normally the values are set via
|
72
65
|
# `::Puma::Configuration.puma_default_options`.
|
73
66
|
#
|
74
|
-
|
67
|
+
# @note The `events` parameter is set to nil, and set to `Events.new` in code.
|
68
|
+
# Often `options` needs to be passed, but `events` does not. Using nil allows
|
69
|
+
# calling code to not require events.rb.
|
70
|
+
#
|
71
|
+
def initialize(app, events = nil, options = {})
|
75
72
|
@app = app
|
76
|
-
@events = events
|
77
|
-
@log_writer = events
|
73
|
+
@events = events || Events.new
|
78
74
|
|
79
75
|
@check, @notify = nil
|
80
76
|
@status = :stop
|
81
77
|
|
82
|
-
@auto_trim_time = 30
|
83
|
-
@reaping_time = 1
|
84
|
-
|
85
78
|
@thread = nil
|
86
79
|
@thread_pool = nil
|
87
80
|
|
88
|
-
@options = options
|
81
|
+
@options = if options.is_a?(UserFileDefaultOptions)
|
82
|
+
options
|
83
|
+
else
|
84
|
+
UserFileDefaultOptions.new(options, Configuration::DEFAULTS)
|
85
|
+
end
|
89
86
|
|
90
|
-
@
|
91
|
-
@
|
92
|
-
@
|
93
|
-
@
|
94
|
-
@
|
95
|
-
@
|
96
|
-
@
|
97
|
-
@
|
87
|
+
@clustered = (@options.fetch :workers, 0) > 0
|
88
|
+
@worker_write = @options[:worker_write]
|
89
|
+
@log_writer = @options.fetch :log_writer, LogWriter.stdio
|
90
|
+
@early_hints = @options[:early_hints]
|
91
|
+
@first_data_timeout = @options[:first_data_timeout]
|
92
|
+
@persistent_timeout = @options[:persistent_timeout]
|
93
|
+
@idle_timeout = @options[:idle_timeout]
|
94
|
+
@min_threads = @options[:min_threads]
|
95
|
+
@max_threads = @options[:max_threads]
|
96
|
+
@queue_requests = @options[:queue_requests]
|
97
|
+
@max_fast_inline = @options[:max_fast_inline]
|
98
|
+
@enable_keep_alives = @options[:enable_keep_alives]
|
99
|
+
@io_selector_backend = @options[:io_selector_backend]
|
100
|
+
@http_content_length_limit = @options[:http_content_length_limit]
|
101
|
+
|
102
|
+
# make this a hash, since we prefer `key?` over `include?`
|
103
|
+
@supported_http_methods =
|
104
|
+
if @options[:supported_http_methods] == :any
|
105
|
+
:any
|
106
|
+
else
|
107
|
+
if (ary = @options[:supported_http_methods])
|
108
|
+
ary
|
109
|
+
else
|
110
|
+
SUPPORTED_HTTP_METHODS
|
111
|
+
end.sort.product([nil]).to_h.freeze
|
112
|
+
end
|
98
113
|
|
99
114
|
temp = !!(@options[:environment] =~ /\A(development|test)\z/)
|
100
115
|
@leak_stack_on_error = @options[:environment] ? temp : true
|
101
116
|
|
102
|
-
@binder = Binder.new(
|
117
|
+
@binder = Binder.new(log_writer)
|
103
118
|
|
104
119
|
ENV['RACK_ENV'] ||= "development"
|
105
120
|
|
@@ -108,6 +123,8 @@ module Puma
|
|
108
123
|
@precheck_closing = true
|
109
124
|
|
110
125
|
@requests_count = 0
|
126
|
+
|
127
|
+
@idle_timeout_reached = false
|
111
128
|
end
|
112
129
|
|
113
130
|
def inherit_binder(bind)
|
@@ -117,7 +134,7 @@ module Puma
|
|
117
134
|
class << self
|
118
135
|
# @!attribute [r] current
|
119
136
|
def current
|
120
|
-
Thread.current
|
137
|
+
Thread.current.puma_server
|
121
138
|
end
|
122
139
|
|
123
140
|
# :nodoc:
|
@@ -195,12 +212,12 @@ module Puma
|
|
195
212
|
|
196
213
|
# @!attribute [r] backlog
|
197
214
|
def backlog
|
198
|
-
@thread_pool
|
215
|
+
@thread_pool&.backlog
|
199
216
|
end
|
200
217
|
|
201
218
|
# @!attribute [r] running
|
202
219
|
def running
|
203
|
-
@thread_pool
|
220
|
+
@thread_pool&.spawned
|
204
221
|
end
|
205
222
|
|
206
223
|
|
@@ -213,7 +230,12 @@ module Puma
|
|
213
230
|
# value would be 4 until it finishes processing.
|
214
231
|
# @!attribute [r] pool_capacity
|
215
232
|
def pool_capacity
|
216
|
-
@thread_pool
|
233
|
+
@thread_pool&.pool_capacity
|
234
|
+
end
|
235
|
+
|
236
|
+
# @!attribute [r] busy_threads
|
237
|
+
def busy_threads
|
238
|
+
@thread_pool&.busy_threads
|
217
239
|
end
|
218
240
|
|
219
241
|
# Runs the server.
|
@@ -229,29 +251,15 @@ module Puma
|
|
229
251
|
|
230
252
|
@status = :run
|
231
253
|
|
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]
|
254
|
+
@thread_pool = ThreadPool.new(thread_name, options) { |client| process_client client }
|
242
255
|
|
243
256
|
if @queue_requests
|
244
|
-
@reactor = Reactor.new(@io_selector_backend
|
257
|
+
@reactor = Reactor.new(@io_selector_backend) { |c| reactor_wakeup c }
|
245
258
|
@reactor.run
|
246
259
|
end
|
247
260
|
|
248
|
-
if
|
249
|
-
|
250
|
-
end
|
251
|
-
|
252
|
-
if @auto_trim_time
|
253
|
-
@thread_pool.auto_trim!(@auto_trim_time)
|
254
|
-
end
|
261
|
+
@thread_pool.auto_reap! if options[:reaping_time]
|
262
|
+
@thread_pool.auto_trim! if @min_threads != @max_threads && options[:auto_trim_time]
|
255
263
|
|
256
264
|
@check, @notify = Puma::Util.pipe unless @notify
|
257
265
|
|
@@ -315,29 +323,49 @@ module Puma
|
|
315
323
|
sockets = [check] + @binder.ios
|
316
324
|
pool = @thread_pool
|
317
325
|
queue_requests = @queue_requests
|
318
|
-
drain =
|
326
|
+
drain = options[:drain_on_shutdown] ? 0 : nil
|
319
327
|
|
320
|
-
addr_send_name, addr_value = case
|
328
|
+
addr_send_name, addr_value = case options[:remote_address]
|
321
329
|
when :value
|
322
|
-
[:peerip=,
|
330
|
+
[:peerip=, options[:remote_address_value]]
|
323
331
|
when :header
|
324
|
-
[:remote_addr_header=,
|
332
|
+
[:remote_addr_header=, options[:remote_address_header]]
|
325
333
|
when :proxy_protocol
|
326
|
-
[:expect_proxy_proto=,
|
334
|
+
[:expect_proxy_proto=, options[:remote_address_proxy_protocol]]
|
327
335
|
else
|
328
336
|
[nil, nil]
|
329
337
|
end
|
330
338
|
|
331
339
|
while @status == :run || (drain && shutting_down?)
|
332
340
|
begin
|
333
|
-
ios = IO.select sockets, nil, nil, (shutting_down? ? 0 :
|
334
|
-
|
341
|
+
ios = IO.select sockets, nil, nil, (shutting_down? ? 0 : @idle_timeout)
|
342
|
+
unless ios
|
343
|
+
unless shutting_down?
|
344
|
+
@idle_timeout_reached = true
|
345
|
+
|
346
|
+
if @clustered
|
347
|
+
@worker_write << "#{PipeRequest::PIPE_IDLE}#{Process.pid}\n" rescue nil
|
348
|
+
next
|
349
|
+
else
|
350
|
+
@log_writer.log "- Idle timeout reached"
|
351
|
+
@status = :stop
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
break
|
356
|
+
end
|
357
|
+
|
358
|
+
if @idle_timeout_reached && @clustered
|
359
|
+
@idle_timeout_reached = false
|
360
|
+
@worker_write << "#{PipeRequest::PIPE_IDLE}#{Process.pid}\n" rescue nil
|
361
|
+
end
|
362
|
+
|
335
363
|
ios.first.each do |sock|
|
336
364
|
if sock == check
|
337
365
|
break if handle_check
|
338
366
|
else
|
339
367
|
pool.wait_until_not_full
|
340
|
-
pool.wait_for_less_busy_worker(
|
368
|
+
pool.wait_for_less_busy_worker(options[:wait_for_less_busy_worker]) if @clustered
|
341
369
|
|
342
370
|
io = begin
|
343
371
|
sock.accept_nonblock
|
@@ -347,6 +375,7 @@ module Puma
|
|
347
375
|
drain += 1 if shutting_down?
|
348
376
|
pool << Client.new(io, @binder.env(sock)).tap { |c|
|
349
377
|
c.listener = sock
|
378
|
+
c.http_content_length_limit = @http_content_length_limit
|
350
379
|
c.send(addr_send_name, addr_value) if addr_value
|
351
380
|
}
|
352
381
|
end
|
@@ -355,27 +384,27 @@ module Puma
|
|
355
384
|
# In the case that any of the sockets are unexpectedly close.
|
356
385
|
raise
|
357
386
|
rescue StandardError => e
|
358
|
-
@
|
387
|
+
@log_writer.unknown_error e, nil, "Listen loop"
|
359
388
|
end
|
360
389
|
end
|
361
390
|
|
362
|
-
@
|
391
|
+
@log_writer.debug "Drained #{drain} additional connections." if drain
|
363
392
|
@events.fire :state, @status
|
364
393
|
|
365
394
|
if queue_requests
|
366
395
|
@queue_requests = false
|
367
396
|
@reactor.shutdown
|
368
397
|
end
|
398
|
+
|
369
399
|
graceful_shutdown if @status == :stop || @status == :restart
|
370
400
|
rescue Exception => e
|
371
|
-
@
|
401
|
+
@log_writer.unknown_error e, nil, "Exception handling servers"
|
372
402
|
ensure
|
373
|
-
# RuntimeError is Ruby 2.2 issue, can't modify frozen IOError
|
374
403
|
# Errno::EBADF is infrequently raised
|
375
404
|
[@check, @notify].each do |io|
|
376
405
|
begin
|
377
406
|
io.close unless io.closed?
|
378
|
-
rescue Errno::EBADF
|
407
|
+
rescue Errno::EBADF
|
379
408
|
end
|
380
409
|
end
|
381
410
|
@notify = nil
|
@@ -414,11 +443,11 @@ module Puma
|
|
414
443
|
# returning.
|
415
444
|
#
|
416
445
|
# Return true if one or more requests were processed.
|
417
|
-
def process_client(client
|
446
|
+
def process_client(client)
|
418
447
|
# Advertise this server into the thread
|
419
|
-
Thread.current
|
448
|
+
Thread.current.puma_server = self
|
420
449
|
|
421
|
-
clean_thread_locals =
|
450
|
+
clean_thread_locals = options[:clean_thread_locals]
|
422
451
|
close_socket = true
|
423
452
|
|
424
453
|
requests = 0
|
@@ -440,15 +469,13 @@ module Puma
|
|
440
469
|
|
441
470
|
while true
|
442
471
|
@requests_count += 1
|
443
|
-
case handle_request(client,
|
472
|
+
case handle_request(client, requests + 1)
|
444
473
|
when false
|
445
474
|
break
|
446
475
|
when :async
|
447
476
|
close_socket = false
|
448
477
|
break
|
449
478
|
when true
|
450
|
-
buffer.reset
|
451
|
-
|
452
479
|
ThreadPool.clean_thread_locals if clean_thread_locals
|
453
480
|
|
454
481
|
requests += 1
|
@@ -478,11 +505,11 @@ module Puma
|
|
478
505
|
end
|
479
506
|
true
|
480
507
|
rescue StandardError => e
|
481
|
-
client_error(e, client)
|
508
|
+
client_error(e, client, requests)
|
482
509
|
# The ensure tries to close +client+ down
|
483
510
|
requests > 0
|
484
511
|
ensure
|
485
|
-
|
512
|
+
client.io_buffer.reset
|
486
513
|
|
487
514
|
begin
|
488
515
|
client.close if close_socket
|
@@ -490,7 +517,7 @@ module Puma
|
|
490
517
|
Puma::Util.purge_interrupt_queue
|
491
518
|
# Already closed
|
492
519
|
rescue StandardError => e
|
493
|
-
@
|
520
|
+
@log_writer.unknown_error e, nil, "Client"
|
494
521
|
end
|
495
522
|
end
|
496
523
|
end
|
@@ -506,30 +533,30 @@ module Puma
|
|
506
533
|
# :nocov:
|
507
534
|
|
508
535
|
# Handle various error types thrown by Client I/O operations.
|
509
|
-
def client_error(e, client)
|
536
|
+
def client_error(e, client, requests = 1)
|
510
537
|
# Swallow, do not log
|
511
538
|
return if [ConnectionError, EOFError].include?(e.class)
|
512
539
|
|
513
|
-
lowlevel_error(e, client.env)
|
514
540
|
case e
|
515
541
|
when MiniSSL::SSLError
|
516
|
-
|
542
|
+
lowlevel_error(e, client.env)
|
543
|
+
@log_writer.ssl_error e, client.io
|
517
544
|
when HttpParserError
|
518
|
-
client
|
519
|
-
@
|
545
|
+
response_to_error(client, requests, e, 400)
|
546
|
+
@log_writer.parse_error e, client
|
520
547
|
when HttpParserError501
|
521
|
-
client
|
522
|
-
@
|
548
|
+
response_to_error(client, requests, e, 501)
|
549
|
+
@log_writer.parse_error e, client
|
523
550
|
else
|
524
|
-
client
|
525
|
-
@
|
551
|
+
response_to_error(client, requests, e, 500)
|
552
|
+
@log_writer.unknown_error e, nil, "Read"
|
526
553
|
end
|
527
554
|
end
|
528
555
|
|
529
556
|
# A fallback rack response if +@app+ raises as exception.
|
530
557
|
#
|
531
558
|
def lowlevel_error(e, env, status=500)
|
532
|
-
if handler =
|
559
|
+
if handler = options[:lowlevel_error_handler]
|
533
560
|
if handler.arity == 1
|
534
561
|
return handler.call(e)
|
535
562
|
elsif handler.arity == 2
|
@@ -543,14 +570,20 @@ module Puma
|
|
543
570
|
backtrace = e.backtrace.nil? ? '<no backtrace available>' : e.backtrace.join("\n")
|
544
571
|
[status, {}, ["Puma caught this error: #{e.message} (#{e.class})\n#{backtrace}"]]
|
545
572
|
else
|
546
|
-
[status, {}, ["
|
573
|
+
[status, {}, [""]]
|
547
574
|
end
|
548
575
|
end
|
549
576
|
|
577
|
+
def response_to_error(client, requests, err, status_code)
|
578
|
+
status, headers, res_body = lowlevel_error(err, client.env, status_code)
|
579
|
+
prepare_response(status, headers, res_body, requests, client)
|
580
|
+
end
|
581
|
+
private :response_to_error
|
582
|
+
|
550
583
|
# Wait for all outstanding requests to finish.
|
551
584
|
#
|
552
585
|
def graceful_shutdown
|
553
|
-
if
|
586
|
+
if options[:shutdown_debug]
|
554
587
|
threads = Thread.list
|
555
588
|
total = threads.size
|
556
589
|
|
@@ -570,7 +603,7 @@ module Puma
|
|
570
603
|
end
|
571
604
|
|
572
605
|
if @thread_pool
|
573
|
-
if timeout =
|
606
|
+
if timeout = options[:force_shutdown_after]
|
574
607
|
@thread_pool.shutdown timeout.to_f
|
575
608
|
else
|
576
609
|
@thread_pool.shutdown
|
@@ -580,7 +613,7 @@ module Puma
|
|
580
613
|
|
581
614
|
def notify_safely(message)
|
582
615
|
@notify << message
|
583
|
-
rescue IOError, NoMethodError, Errno::EPIPE
|
616
|
+
rescue IOError, NoMethodError, Errno::EPIPE, Errno::EBADF
|
584
617
|
# The server, in another thread, is shutting down
|
585
618
|
Puma::Util.purge_interrupt_queue
|
586
619
|
rescue RuntimeError => e
|
@@ -617,13 +650,39 @@ module Puma
|
|
617
650
|
|
618
651
|
# List of methods invoked by #stats.
|
619
652
|
# @version 5.0.0
|
620
|
-
STAT_METHODS = [:backlog, :running, :pool_capacity, :max_threads, :requests_count].freeze
|
653
|
+
STAT_METHODS = [:backlog, :running, :pool_capacity, :max_threads, :requests_count, :busy_threads].freeze
|
621
654
|
|
622
655
|
# Returns a hash of stats about the running server for reporting purposes.
|
623
656
|
# @version 5.0.0
|
624
657
|
# @!attribute [r] stats
|
658
|
+
# @return [Hash] hash containing stat info from `Server` and `ThreadPool`
|
625
659
|
def stats
|
626
|
-
|
660
|
+
stats = @thread_pool&.stats || {}
|
661
|
+
stats[:max_threads] = @max_threads
|
662
|
+
stats[:requests_count] = @requests_count
|
663
|
+
stats
|
664
|
+
end
|
665
|
+
|
666
|
+
# below are 'delegations' to binder
|
667
|
+
# remove in Puma 7?
|
668
|
+
|
669
|
+
|
670
|
+
def add_tcp_listener(host, port, optimize_for_latency = true, backlog = 1024)
|
671
|
+
@binder.add_tcp_listener host, port, optimize_for_latency, backlog
|
672
|
+
end
|
673
|
+
|
674
|
+
def add_ssl_listener(host, port, ctx, optimize_for_latency = true,
|
675
|
+
backlog = 1024)
|
676
|
+
@binder.add_ssl_listener host, port, ctx, optimize_for_latency, backlog
|
677
|
+
end
|
678
|
+
|
679
|
+
def add_unix_listener(path, umask = nil, mode = nil, backlog = 1024)
|
680
|
+
@binder.add_unix_listener path, umask, mode, backlog
|
681
|
+
end
|
682
|
+
|
683
|
+
# @!attribute [r] connected_ports
|
684
|
+
def connected_ports
|
685
|
+
@binder.connected_ports
|
627
686
|
end
|
628
687
|
end
|
629
688
|
end
|
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
|
@@ -16,26 +16,26 @@ module Puma
|
|
16
16
|
# @!attribute [r] stats
|
17
17
|
def stats
|
18
18
|
{
|
19
|
-
started_at: @started_at
|
20
|
-
}.merge(@server.stats)
|
19
|
+
started_at: utc_iso8601(@started_at)
|
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,9 @@ module Puma
|
|
55
55
|
log "Use Ctrl-C to stop"
|
56
56
|
redirect_io
|
57
57
|
|
58
|
-
@
|
58
|
+
@events.fire_on_booted!
|
59
|
+
|
60
|
+
debug_loaded_extensions("Loaded Extensions:") if @log_writer.debug?
|
59
61
|
|
60
62
|
begin
|
61
63
|
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
|
@@ -59,11 +56,11 @@ module Puma
|
|
59
56
|
end
|
60
57
|
|
61
58
|
ALLOWED_FIELDS.each do |f|
|
62
|
-
define_method f do
|
59
|
+
define_method f.to_sym do
|
63
60
|
@options[f]
|
64
61
|
end
|
65
62
|
|
66
|
-
define_method "#{f}=" do |v|
|
63
|
+
define_method :"#{f}=" do |v|
|
67
64
|
@options[f] = v
|
68
65
|
end
|
69
66
|
end
|