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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +465 -18
  3. data/README.md +152 -42
  4. data/bin/puma-wild +1 -1
  5. data/docs/compile_options.md +34 -0
  6. data/docs/fork_worker.md +12 -4
  7. data/docs/java_options.md +54 -0
  8. data/docs/kubernetes.md +12 -0
  9. data/docs/nginx.md +1 -1
  10. data/docs/plugins.md +4 -0
  11. data/docs/restart.md +1 -0
  12. data/docs/signals.md +2 -2
  13. data/docs/stats.md +8 -3
  14. data/docs/systemd.md +13 -7
  15. data/docs/testing_benchmarks_local_files.md +150 -0
  16. data/docs/testing_test_rackup_ci_files.md +36 -0
  17. data/ext/puma_http11/extconf.rb +27 -17
  18. data/ext/puma_http11/http11_parser.c +1 -1
  19. data/ext/puma_http11/http11_parser.h +1 -1
  20. data/ext/puma_http11/http11_parser.java.rl +2 -2
  21. data/ext/puma_http11/http11_parser.rl +2 -2
  22. data/ext/puma_http11/http11_parser_common.rl +2 -2
  23. data/ext/puma_http11/mini_ssl.c +137 -19
  24. data/ext/puma_http11/org/jruby/puma/Http11.java +31 -10
  25. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
  26. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +157 -53
  27. data/ext/puma_http11/puma_http11.c +21 -10
  28. data/lib/puma/app/status.rb +4 -4
  29. data/lib/puma/binder.rb +60 -55
  30. data/lib/puma/cli.rb +22 -20
  31. data/lib/puma/client.rb +93 -30
  32. data/lib/puma/cluster/worker.rb +27 -17
  33. data/lib/puma/cluster/worker_handle.rb +8 -6
  34. data/lib/puma/cluster.rb +121 -47
  35. data/lib/puma/commonlogger.rb +21 -14
  36. data/lib/puma/configuration.rb +101 -65
  37. data/lib/puma/const.rb +141 -93
  38. data/lib/puma/control_cli.rb +19 -15
  39. data/lib/puma/detect.rb +7 -4
  40. data/lib/puma/dsl.rb +521 -88
  41. data/lib/puma/error_logger.rb +22 -13
  42. data/lib/puma/events.rb +6 -126
  43. data/lib/puma/io_buffer.rb +39 -4
  44. data/lib/puma/jruby_restart.rb +0 -15
  45. data/lib/puma/launcher/bundle_pruner.rb +104 -0
  46. data/lib/puma/launcher.rb +121 -181
  47. data/lib/puma/log_writer.rb +147 -0
  48. data/lib/puma/minissl/context_builder.rb +27 -12
  49. data/lib/puma/minissl.rb +105 -11
  50. data/lib/puma/null_io.rb +42 -2
  51. data/lib/puma/plugin/systemd.rb +90 -0
  52. data/lib/puma/plugin/tmp_restart.rb +1 -1
  53. data/lib/puma/puma_http11.jar +0 -0
  54. data/lib/puma/rack/builder.rb +6 -6
  55. data/lib/puma/rack/urlmap.rb +1 -1
  56. data/lib/puma/rack_default.rb +19 -4
  57. data/lib/puma/reactor.rb +19 -10
  58. data/lib/puma/request.rb +368 -169
  59. data/lib/puma/runner.rb +65 -22
  60. data/lib/puma/sd_notify.rb +146 -0
  61. data/lib/puma/server.rb +161 -102
  62. data/lib/puma/single.rb +13 -11
  63. data/lib/puma/state_file.rb +3 -6
  64. data/lib/puma/thread_pool.rb +71 -21
  65. data/lib/puma/util.rb +1 -12
  66. data/lib/puma.rb +9 -10
  67. data/lib/rack/handler/puma.rb +116 -86
  68. data/tools/Dockerfile +2 -2
  69. metadata +17 -12
  70. data/lib/puma/queue_close.rb +0 -26
  71. data/lib/puma/systemd.rb +0 -46
  72. 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
- require 'puma/thread_pool'
6
- require 'puma/const'
7
- require 'puma/events'
8
- require 'puma/null_io'
9
- require 'puma/reactor'
10
- require 'puma/client'
11
- require 'puma/binder'
12
- require 'puma/util'
13
- require 'puma/io_buffer'
14
- require 'puma/request'
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
- # +events+ is an object which will be called when certain error events occur
65
- # to be handled. See Puma::Events for the list of current methods to implement.
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
- def initialize(app, events=Events.stdio, options={})
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
- @early_hints = options.fetch :early_hints, nil
91
- @first_data_timeout = options.fetch :first_data_timeout, FIRST_DATA_TIMEOUT
92
- @min_threads = options.fetch :min_threads, 0
93
- @max_threads = options.fetch :max_threads , (Puma.mri? ? 5 : 16)
94
- @persistent_timeout = options.fetch :persistent_timeout, PERSISTENT_TIMEOUT
95
- @queue_requests = options.fetch :queue_requests, true
96
- @max_fast_inline = options.fetch :max_fast_inline, MAX_FAST_INLINE
97
- @io_selector_backend = options.fetch :io_selector_backend, :auto
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(events)
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[ThreadLocalKey]
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 and @thread_pool.backlog
215
+ @thread_pool&.backlog
199
216
  end
200
217
 
201
218
  # @!attribute [r] running
202
219
  def running
203
- @thread_pool and @thread_pool.spawned
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 and @thread_pool.pool_capacity
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, &method(:reactor_wakeup))
257
+ @reactor = Reactor.new(@io_selector_backend) { |c| reactor_wakeup c }
245
258
  @reactor.run
246
259
  end
247
260
 
248
- if @reaping_time
249
- @thread_pool.auto_reap!(@reaping_time)
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 = @options[:drain_on_shutdown] ? 0 : nil
326
+ drain = options[:drain_on_shutdown] ? 0 : nil
319
327
 
320
- addr_send_name, addr_value = case @options[:remote_address]
328
+ addr_send_name, addr_value = case options[:remote_address]
321
329
  when :value
322
- [:peerip=, @options[:remote_address_value]]
330
+ [:peerip=, options[:remote_address_value]]
323
331
  when :header
324
- [:remote_addr_header=, @options[:remote_address_header]]
332
+ [:remote_addr_header=, options[:remote_address_header]]
325
333
  when :proxy_protocol
326
- [:expect_proxy_proto=, @options[:remote_address_proxy_protocol]]
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 : nil)
334
- break unless ios
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(@options[: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
- @events.unknown_error e, nil, "Listen loop"
387
+ @log_writer.unknown_error e, nil, "Listen loop"
359
388
  end
360
389
  end
361
390
 
362
- @events.debug "Drained #{drain} additional connections." if drain
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
- @events.unknown_error e, nil, "Exception handling servers"
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, RuntimeError
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, buffer)
446
+ def process_client(client)
418
447
  # Advertise this server into the thread
419
- Thread.current[ThreadLocalKey] = self
448
+ Thread.current.puma_server = self
420
449
 
421
- clean_thread_locals = @options[: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, buffer, requests + 1)
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
- buffer.reset
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
- @events.unknown_error e, nil, "Client"
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
- @events.ssl_error e, client.io
542
+ lowlevel_error(e, client.env)
543
+ @log_writer.ssl_error e, client.io
517
544
  when HttpParserError
518
- client.write_error(400)
519
- @events.parse_error e, client
545
+ response_to_error(client, requests, e, 400)
546
+ @log_writer.parse_error e, client
520
547
  when HttpParserError501
521
- client.write_error(501)
522
- @events.parse_error e, client
548
+ response_to_error(client, requests, e, 501)
549
+ @log_writer.parse_error e, client
523
550
  else
524
- client.write_error(500)
525
- @events.unknown_error e, nil, "Read"
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 = @options[:lowlevel_error_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, {}, ["An unhandled lowlevel error occurred. The application logs may have details.\n"]]
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 @options[:shutdown_debug]
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 = @options[:force_shutdown_after]
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
- STAT_METHODS.map {|name| [name, send(name) || 0]}.to_h
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
- require 'puma/runner'
4
- require 'puma/detect'
5
- require 'puma/plugin'
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.utc.iso8601
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.begin_restart
24
+ @server&.begin_restart
25
25
  end
26
26
 
27
27
  def stop
28
- @server.stop(false) if @server
28
+ @server&.stop false
29
29
  end
30
30
 
31
31
  def halt
32
- @server.halt
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.stop(true) if @control
38
- @server.stop(true) if @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
- @launcher.events.fire_on_booted!
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
@@ -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".dup
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