puma 5.6.4 → 6.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +372 -6
  3. data/LICENSE +0 -0
  4. data/README.md +79 -29
  5. data/bin/puma-wild +1 -1
  6. data/docs/architecture.md +0 -0
  7. data/docs/compile_options.md +34 -0
  8. data/docs/deployment.md +0 -0
  9. data/docs/fork_worker.md +1 -3
  10. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  11. data/docs/images/puma-connection-flow.png +0 -0
  12. data/docs/images/puma-general-arch.png +0 -0
  13. data/docs/jungle/README.md +0 -0
  14. data/docs/jungle/rc.d/README.md +0 -0
  15. data/docs/jungle/rc.d/puma.conf +0 -0
  16. data/docs/kubernetes.md +12 -0
  17. data/docs/nginx.md +1 -1
  18. data/docs/plugins.md +0 -0
  19. data/docs/rails_dev_mode.md +0 -0
  20. data/docs/restart.md +1 -0
  21. data/docs/signals.md +0 -0
  22. data/docs/stats.md +0 -0
  23. data/docs/systemd.md +3 -6
  24. data/docs/testing_benchmarks_local_files.md +150 -0
  25. data/docs/testing_test_rackup_ci_files.md +36 -0
  26. data/ext/puma_http11/PumaHttp11Service.java +0 -0
  27. data/ext/puma_http11/ext_help.h +0 -0
  28. data/ext/puma_http11/extconf.rb +22 -10
  29. data/ext/puma_http11/http11_parser.c +1 -1
  30. data/ext/puma_http11/http11_parser.h +1 -1
  31. data/ext/puma_http11/http11_parser.java.rl +2 -2
  32. data/ext/puma_http11/http11_parser.rl +2 -2
  33. data/ext/puma_http11/http11_parser_common.rl +2 -2
  34. data/ext/puma_http11/mini_ssl.c +153 -27
  35. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
  36. data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
  37. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
  38. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +167 -65
  39. data/ext/puma_http11/puma_http11.c +17 -9
  40. data/lib/puma/app/status.rb +7 -4
  41. data/lib/puma/binder.rb +51 -54
  42. data/lib/puma/cli.rb +16 -18
  43. data/lib/puma/client.rb +100 -26
  44. data/lib/puma/cluster/worker.rb +18 -11
  45. data/lib/puma/cluster/worker_handle.rb +4 -1
  46. data/lib/puma/cluster.rb +102 -40
  47. data/lib/puma/commonlogger.rb +21 -14
  48. data/lib/puma/configuration.rb +77 -59
  49. data/lib/puma/const.rb +129 -92
  50. data/lib/puma/control_cli.rb +33 -23
  51. data/lib/puma/detect.rb +7 -4
  52. data/lib/puma/dsl.rb +251 -53
  53. data/lib/puma/error_logger.rb +18 -9
  54. data/lib/puma/events.rb +6 -126
  55. data/lib/puma/io_buffer.rb +39 -4
  56. data/lib/puma/jruby_restart.rb +2 -1
  57. data/lib/puma/json_serialization.rb +0 -0
  58. data/lib/puma/launcher/bundle_pruner.rb +104 -0
  59. data/lib/puma/launcher.rb +113 -175
  60. data/lib/puma/log_writer.rb +147 -0
  61. data/lib/puma/minissl/context_builder.rb +26 -12
  62. data/lib/puma/minissl.rb +113 -15
  63. data/lib/puma/null_io.rb +21 -2
  64. data/lib/puma/plugin/systemd.rb +90 -0
  65. data/lib/puma/plugin/tmp_restart.rb +1 -1
  66. data/lib/puma/plugin.rb +0 -0
  67. data/lib/puma/rack/builder.rb +6 -6
  68. data/lib/puma/rack/urlmap.rb +1 -1
  69. data/lib/puma/rack_default.rb +19 -4
  70. data/lib/puma/reactor.rb +19 -10
  71. data/lib/puma/request.rb +365 -166
  72. data/lib/puma/runner.rb +56 -20
  73. data/lib/puma/sd_notify.rb +149 -0
  74. data/lib/puma/server.rb +137 -87
  75. data/lib/puma/single.rb +13 -11
  76. data/lib/puma/state_file.rb +4 -6
  77. data/lib/puma/thread_pool.rb +57 -19
  78. data/lib/puma/util.rb +12 -14
  79. data/lib/puma.rb +12 -11
  80. data/lib/rack/handler/puma.rb +113 -86
  81. data/tools/Dockerfile +2 -2
  82. data/tools/trickletest.rb +0 -0
  83. metadata +11 -6
  84. data/lib/puma/queue_close.rb +0 -26
  85. data/lib/puma/systemd.rb +0 -46
@@ -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, min, max, *extra, &block)
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,19 @@ module Puma
40
42
  @waiting = 0
41
43
 
42
44
  @name = name
43
- @min = Integer(min)
44
- @max = Integer(max)
45
+ @min = Integer(options[:min_threads])
46
+ @max = Integer(options[:max_threads])
47
+ # Not an 'exposed' option, options[:pool_shutdown_grace_time] is used in CI
48
+ # to shorten @shutdown_grace_time from SHUTDOWN_GRACE_TIME. Parallel CI
49
+ # makes stubbing constants difficult.
50
+ @shutdown_grace_time = Float(options[:pool_shutdown_grace_time] || SHUTDOWN_GRACE_TIME)
45
51
  @block = block
46
- @extra = extra
52
+ @out_of_band = options[:out_of_band]
53
+ @clean_thread_locals = options[:clean_thread_locals]
54
+ @before_thread_start = options[:before_thread_start]
55
+ @before_thread_exit = options[:before_thread_exit]
56
+ @reaping_time = options[:reaping_time]
57
+ @auto_trim_time = options[:auto_trim_time]
47
58
 
48
59
  @shutdown = false
49
60
 
@@ -62,14 +73,11 @@ module Puma
62
73
  end
63
74
  end
64
75
 
65
- @clean_thread_locals = false
66
76
  @force_shutdown = false
67
77
  @shutdown_mutex = Mutex.new
68
78
  end
69
79
 
70
80
  attr_reader :spawned, :trim_requested, :waiting
71
- attr_accessor :clean_thread_locals
72
- attr_accessor :out_of_band_hook # @version 5.0.0
73
81
 
74
82
  def self.clean_thread_locals
75
83
  Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods
@@ -101,6 +109,7 @@ module Puma
101
109
  def spawn_thread
102
110
  @spawned += 1
103
111
 
112
+ trigger_before_thread_start_hooks
104
113
  th = Thread.new(@spawned) do |spawned|
105
114
  Puma.set_thread_name '%s tp %03i' % [@name, spawned]
106
115
  todo = @todo
@@ -109,8 +118,6 @@ module Puma
109
118
  not_empty = @not_empty
110
119
  not_full = @not_full
111
120
 
112
- extra = @extra.map { |i| i.new }
113
-
114
121
  while true
115
122
  work = nil
116
123
 
@@ -121,6 +128,7 @@ module Puma
121
128
  @spawned -= 1
122
129
  @workers.delete th
123
130
  not_full.signal
131
+ trigger_before_thread_exit_hooks
124
132
  Thread.exit
125
133
  end
126
134
 
@@ -144,7 +152,7 @@ module Puma
144
152
  end
145
153
 
146
154
  begin
147
- @out_of_band_pending = true if block.call(work, *extra)
155
+ @out_of_band_pending = true if block.call(work)
148
156
  rescue Exception => e
149
157
  STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})"
150
158
  end
@@ -158,14 +166,44 @@ module Puma
158
166
 
159
167
  private :spawn_thread
160
168
 
169
+ def trigger_before_thread_start_hooks
170
+ return unless @before_thread_start&.any?
171
+
172
+ @before_thread_start.each do |b|
173
+ begin
174
+ b.call
175
+ rescue Exception => e
176
+ STDERR.puts "WARNING before_thread_start hook failed with exception (#{e.class}) #{e.message}"
177
+ end
178
+ end
179
+ nil
180
+ end
181
+
182
+ private :trigger_before_thread_start_hooks
183
+
184
+ def trigger_before_thread_exit_hooks
185
+ return unless @before_thread_exit&.any?
186
+
187
+ @before_thread_exit.each do |b|
188
+ begin
189
+ b.call
190
+ rescue Exception => e
191
+ STDERR.puts "WARNING before_thread_exit hook failed with exception (#{e.class}) #{e.message}"
192
+ end
193
+ end
194
+ nil
195
+ end
196
+
197
+ private :trigger_before_thread_exit_hooks
198
+
161
199
  # @version 5.0.0
162
200
  def trigger_out_of_band_hook
163
- return false unless out_of_band_hook && out_of_band_hook.any?
201
+ return false unless @out_of_band&.any?
164
202
 
165
203
  # we execute on idle hook when all threads are free
166
204
  return false unless @spawned == @waiting
167
205
 
168
- out_of_band_hook.each(&:call)
206
+ @out_of_band.each(&:call)
169
207
  true
170
208
  rescue Exception => e
171
209
  STDERR.puts "Exception calling out_of_band_hook: #{e.message} (#{e.class})"
@@ -319,12 +357,12 @@ module Puma
319
357
  end
320
358
  end
321
359
 
322
- def auto_trim!(timeout=30)
360
+ def auto_trim!(timeout=@auto_trim_time)
323
361
  @auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
324
362
  @auto_trim.start!
325
363
  end
326
364
 
327
- def auto_reap!(timeout=5)
365
+ def auto_reap!(timeout=@reaping_time)
328
366
  @reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
329
367
  @reaper.start!
330
368
  end
@@ -344,8 +382,8 @@ module Puma
344
382
 
345
383
  # Tell all threads in the pool to exit and wait for them to finish.
346
384
  # Wait +timeout+ seconds then raise +ForceShutdown+ in remaining threads.
347
- # Next, wait an extra +grace+ seconds then force-kill remaining threads.
348
- # Finally, wait +kill_grace+ seconds for remaining threads to exit.
385
+ # Next, wait an extra +@shutdown_grace_time+ seconds then force-kill remaining
386
+ # threads. Finally, wait 1 second for remaining threads to exit.
349
387
  #
350
388
  def shutdown(timeout=-1)
351
389
  threads = with_mutex do
@@ -354,8 +392,8 @@ module Puma
354
392
  @not_empty.broadcast
355
393
  @not_full.broadcast
356
394
 
357
- @auto_trim.stop if @auto_trim
358
- @reaper.stop if @reaper
395
+ @auto_trim&.stop
396
+ @reaper&.stop
359
397
  # dup workers so that we join them all safely
360
398
  @workers.dup
361
399
  end
@@ -382,7 +420,7 @@ module Puma
382
420
  t.raise ForceShutdown if t[:with_force_shutdown]
383
421
  end
384
422
  end
385
- join.call(SHUTDOWN_GRACE_TIME)
423
+ join.call(@shutdown_grace_time)
386
424
 
387
425
  # If threads are _still_ running, forcefully kill them and wait to finish.
388
426
  threads.each(&:kill)
data/lib/puma/util.rb CHANGED
@@ -17,29 +17,27 @@ module Puma
17
17
  Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
18
18
  end
19
19
 
20
- # Unescapes a URI escaped string with +encoding+. +encoding+ will be the
21
- # target encoding of the string returned, and it defaults to UTF-8
20
+ # Escapes and unescapes a URI escaped string with
21
+ # +encoding+. +encoding+ will be the target encoding of the string
22
+ # returned, and it defaults to UTF-8
22
23
  if defined?(::Encoding)
24
+ def escape(s, encoding = Encoding::UTF_8)
25
+ URI.encode_www_form_component(s, encoding)
26
+ end
27
+
23
28
  def unescape(s, encoding = Encoding::UTF_8)
24
29
  URI.decode_www_form_component(s, encoding)
25
30
  end
26
31
  else
27
- def unescape(s, encoding = nil)
28
- URI.decode_www_form_component(s, encoding)
32
+ def escape(s, encoding = nil)
33
+ URI.encode_www_form_component(s, encoding)
29
34
  end
30
- end
31
- module_function :unescape
32
35
 
33
- # @version 5.0.0
34
- def nakayoshi_gc(events)
35
- events.log "! Promoting existing objects to old generation..."
36
- 4.times { GC.start(full_mark: false) }
37
- if GC.respond_to?(:compact)
38
- events.log "! Compacting..."
39
- GC.compact
36
+ def unescape(s, encoding = nil)
37
+ URI.decode_www_form_component(s, encoding)
40
38
  end
41
- events.log "! Friendly fork preparation complete."
42
39
  end
40
+ module_function :unescape, :escape
43
41
 
44
42
  DEFAULT_SEP = /[&;] */n
45
43
 
data/lib/puma.rb CHANGED
@@ -3,30 +3,33 @@
3
3
  # Standard libraries
4
4
  require 'socket'
5
5
  require 'tempfile'
6
- require 'time'
7
- require 'etc'
8
6
  require 'uri'
9
7
  require 'stringio'
10
8
 
11
9
  require 'thread'
12
10
 
11
+ # use require, see https://github.com/puma/puma/pull/2381
13
12
  require 'puma/puma_http11'
14
- require 'puma/detect'
15
- require 'puma/json_serialization'
13
+
14
+ require_relative 'puma/detect'
15
+ require_relative 'puma/json_serialization'
16
16
 
17
17
  module Puma
18
- autoload :Const, 'puma/const'
19
- autoload :Server, 'puma/server'
20
- autoload :Launcher, 'puma/launcher'
18
+ # when Puma is loaded via `Puma::CLI`, all files are loaded via
19
+ # `require_relative`. The below are for non-standard loading
20
+ autoload :Const, "#{__dir__}/puma/const"
21
+ autoload :Server, "#{__dir__}/puma/server"
22
+ autoload :Launcher, "#{__dir__}/puma/launcher"
23
+ autoload :LogWriter, "#{__dir__}/puma/log_writer"
21
24
 
22
25
  # at present, MiniSSL::Engine is only defined in extension code (puma_http11),
23
26
  # not in minissl.rb
24
27
  HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
25
28
 
26
- HAS_UNIX_SOCKET = Object.const_defined? :UNIXSocket
29
+ HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS
27
30
 
28
31
  if HAS_SSL
29
- require 'puma/minissl'
32
+ require_relative 'puma/minissl'
30
33
  else
31
34
  module MiniSSL
32
35
  # this class is defined so that it exists when Puma is compiled
@@ -69,9 +72,7 @@ module Puma
69
72
  @get_stats.stats
70
73
  end
71
74
 
72
- # Thread name is new in Ruby 2.3
73
75
  def self.set_thread_name(name)
74
- return unless Thread.current.respond_to?(:name=)
75
76
  Thread.current.name = "puma #{name}"
76
77
  end
77
78
  end
@@ -1,114 +1,141 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rack/handler'
4
-
5
- module Rack
6
- module Handler
7
- module Puma
8
- DEFAULT_OPTIONS = {
9
- :Verbose => false,
10
- :Silent => false
11
- }
12
-
13
- def self.config(app, options = {})
14
- require 'puma'
15
- require 'puma/configuration'
16
- require 'puma/events'
17
- require 'puma/launcher'
18
-
19
- default_options = DEFAULT_OPTIONS.dup
20
-
21
- # Libraries pass in values such as :Port and there is no way to determine
22
- # if it is a default provided by the library or a special value provided
23
- # by the user. A special key `user_supplied_options` can be passed. This
24
- # contains an array of all explicitly defined user options. We then
25
- # know that all other values are defaults
26
- if user_supplied_options = options.delete(:user_supplied_options)
27
- (options.keys - user_supplied_options).each do |k|
28
- default_options[k] = options.delete(k)
29
- end
3
+ # This module is used as an 'include' file in code at bottom of file
4
+ module Puma
5
+ module RackHandler
6
+ DEFAULT_OPTIONS = {
7
+ :Verbose => false,
8
+ :Silent => false
9
+ }
10
+
11
+ def config(app, options = {})
12
+ require_relative '../../puma'
13
+ require_relative '../../puma/configuration'
14
+ require_relative '../../puma/log_writer'
15
+ require_relative '../../puma/launcher'
16
+
17
+ default_options = DEFAULT_OPTIONS.dup
18
+
19
+ # Libraries pass in values such as :Port and there is no way to determine
20
+ # if it is a default provided by the library or a special value provided
21
+ # by the user. A special key `user_supplied_options` can be passed. This
22
+ # contains an array of all explicitly defined user options. We then
23
+ # know that all other values are defaults
24
+ if user_supplied_options = options.delete(:user_supplied_options)
25
+ (options.keys - user_supplied_options).each do |k|
26
+ default_options[k] = options.delete(k)
30
27
  end
28
+ end
31
29
 
32
- conf = ::Puma::Configuration.new(options, default_options) do |user_config, file_config, default_config|
33
- if options.delete(:Verbose)
34
- require 'rack/common_logger'
35
- app = Rack::CommonLogger.new(app, STDOUT)
36
- end
30
+ @events = options[:events] || ::Puma::Events.new
37
31
 
38
- if options[:environment]
39
- user_config.environment options[:environment]
32
+ conf = ::Puma::Configuration.new(options, default_options.merge({events: @events})) do |user_config, file_config, default_config|
33
+ if options.delete(:Verbose)
34
+ begin
35
+ require 'rack/commonlogger' # Rack 1.x
36
+ rescue LoadError
37
+ require 'rack/common_logger' # Rack 2 and later
40
38
  end
39
+ app = ::Rack::CommonLogger.new(app, STDOUT)
40
+ end
41
41
 
42
- if options[:Threads]
43
- min, max = options.delete(:Threads).split(':', 2)
44
- user_config.threads min, max
45
- end
42
+ if options[:environment]
43
+ user_config.environment options[:environment]
44
+ end
46
45
 
47
- if options[:Host] || options[:Port]
48
- host = options[:Host] || default_options[:Host]
49
- port = options[:Port] || default_options[:Port]
50
- self.set_host_port_to_config(host, port, user_config)
51
- end
46
+ if options[:Threads]
47
+ min, max = options.delete(:Threads).split(':', 2)
48
+ user_config.threads min, max
49
+ end
52
50
 
53
- if default_options[:Host]
54
- file_config.set_default_host(default_options[:Host])
55
- end
56
- self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
51
+ if options[:Host] || options[:Port]
52
+ host = options[:Host] || default_options[:Host]
53
+ port = options[:Port] || default_options[:Port]
54
+ self.set_host_port_to_config(host, port, user_config)
55
+ end
57
56
 
58
- user_config.app app
57
+ if default_options[:Host]
58
+ file_config.set_default_host(default_options[:Host])
59
59
  end
60
- conf
60
+ self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
61
+
62
+ user_config.app app
61
63
  end
64
+ conf
65
+ end
62
66
 
63
- def self.run(app, **options)
64
- conf = self.config(app, options)
67
+ def run(app, **options)
68
+ conf = self.config(app, options)
65
69
 
66
- events = options.delete(:Silent) ? ::Puma::Events.strings : ::Puma::Events.stdio
70
+ log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
67
71
 
68
- launcher = ::Puma::Launcher.new(conf, :events => events)
72
+ launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer, events: @events)
69
73
 
70
- yield launcher if block_given?
71
- begin
72
- launcher.run
73
- rescue Interrupt
74
- puts "* Gracefully stopping, waiting for requests to finish"
75
- launcher.stop
76
- puts "* Goodbye!"
77
- end
74
+ yield launcher if block_given?
75
+ begin
76
+ launcher.run
77
+ rescue Interrupt
78
+ puts "* Gracefully stopping, waiting for requests to finish"
79
+ launcher.stop
80
+ puts "* Goodbye!"
78
81
  end
82
+ end
79
83
 
80
- def self.valid_options
81
- {
82
- "Host=HOST" => "Hostname to listen on (default: localhost)",
83
- "Port=PORT" => "Port to listen on (default: 8080)",
84
- "Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
85
- "Verbose" => "Don't report each request (default: false)"
86
- }
87
- end
84
+ def valid_options
85
+ {
86
+ "Host=HOST" => "Hostname to listen on (default: localhost)",
87
+ "Port=PORT" => "Port to listen on (default: 8080)",
88
+ "Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
89
+ "Verbose" => "Don't report each request (default: false)"
90
+ }
91
+ end
88
92
 
89
- def self.set_host_port_to_config(host, port, config)
90
- config.clear_binds! if host || port
93
+ def set_host_port_to_config(host, port, config)
94
+ config.clear_binds! if host || port
91
95
 
92
- if host && (host[0,1] == '.' || host[0,1] == '/')
93
- config.bind "unix://#{host}"
94
- elsif host && host =~ /^ssl:\/\//
95
- uri = URI.parse(host)
96
- uri.port ||= port || ::Puma::Configuration::DefaultTCPPort
97
- config.bind uri.to_s
98
- else
96
+ if host && (host[0,1] == '.' || host[0,1] == '/')
97
+ config.bind "unix://#{host}"
98
+ elsif host && host =~ /^ssl:\/\//
99
+ uri = URI.parse(host)
100
+ uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
101
+ config.bind uri.to_s
102
+ else
99
103
 
100
- if host
101
- port ||= ::Puma::Configuration::DefaultTCPPort
102
- end
104
+ if host
105
+ port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
106
+ end
103
107
 
104
- if port
105
- host ||= ::Puma::Configuration::DefaultTCPHost
106
- config.port port, host
107
- end
108
+ if port
109
+ host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
110
+ config.port port, host
108
111
  end
109
112
  end
110
113
  end
114
+ end
115
+ end
111
116
 
112
- register :puma, Puma
117
+ # rackup was removed in Rack 3, it is now a separate gem
118
+ if Object.const_defined? :Rackup
119
+ module Rackup
120
+ module Handler
121
+ module Puma
122
+ class << self
123
+ include ::Puma::RackHandler
124
+ end
125
+ end
126
+ register :puma, Puma
127
+ end
128
+ end
129
+ else
130
+ do_register = Object.const_defined?(:Rack) && Rack.release < '3'
131
+ module Rack
132
+ module Handler
133
+ module Puma
134
+ class << self
135
+ include ::Puma::RackHandler
136
+ end
137
+ end
138
+ end
113
139
  end
140
+ ::Rack::Handler.register(:puma, ::Rack::Handler::Puma) if do_register
114
141
  end
data/tools/Dockerfile CHANGED
@@ -1,6 +1,6 @@
1
1
  # Use this Dockerfile to create minimal reproductions of issues
2
2
 
3
- FROM ruby:3.1
3
+ FROM ruby:3.2
4
4
 
5
5
  # throw errors if Gemfile has been modified since Gemfile.lock
6
6
  RUN bundle config --global frozen 1
@@ -8,7 +8,7 @@ RUN bundle config --global frozen 1
8
8
  WORKDIR /usr/src/app
9
9
 
10
10
  COPY . .
11
- RUN gem install bundler
11
+
12
12
  RUN bundle install
13
13
  RUN bundle exec rake compile
14
14
 
data/tools/trickletest.rb CHANGED
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.6.4
4
+ version: 6.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Phoenix
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 1980-01-01 00:00:00.000000000 Z
11
+ date: 2024-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nio4r
@@ -62,6 +62,8 @@ files:
62
62
  - docs/signals.md
63
63
  - docs/stats.md
64
64
  - docs/systemd.md
65
+ - docs/testing_benchmarks_local_files.md
66
+ - docs/testing_test_rackup_ci_files.md
65
67
  - ext/puma_http11/PumaHttp11Service.java
66
68
  - ext/puma_http11/ext_help.h
67
69
  - ext/puma_http11/extconf.rb
@@ -96,22 +98,24 @@ files:
96
98
  - lib/puma/jruby_restart.rb
97
99
  - lib/puma/json_serialization.rb
98
100
  - lib/puma/launcher.rb
101
+ - lib/puma/launcher/bundle_pruner.rb
102
+ - lib/puma/log_writer.rb
99
103
  - lib/puma/minissl.rb
100
104
  - lib/puma/minissl/context_builder.rb
101
105
  - lib/puma/null_io.rb
102
106
  - lib/puma/plugin.rb
107
+ - lib/puma/plugin/systemd.rb
103
108
  - lib/puma/plugin/tmp_restart.rb
104
- - lib/puma/queue_close.rb
105
109
  - lib/puma/rack/builder.rb
106
110
  - lib/puma/rack/urlmap.rb
107
111
  - lib/puma/rack_default.rb
108
112
  - lib/puma/reactor.rb
109
113
  - lib/puma/request.rb
110
114
  - lib/puma/runner.rb
115
+ - lib/puma/sd_notify.rb
111
116
  - lib/puma/server.rb
112
117
  - lib/puma/single.rb
113
118
  - lib/puma/state_file.rb
114
- - lib/puma/systemd.rb
115
119
  - lib/puma/thread_pool.rb
116
120
  - lib/puma/util.rb
117
121
  - lib/rack/handler/puma.rb
@@ -125,6 +129,7 @@ metadata:
125
129
  changelog_uri: https://github.com/puma/puma/blob/master/History.md
126
130
  homepage_uri: https://puma.io
127
131
  source_code_uri: https://github.com/puma/puma
132
+ rubygems_mfa_required: 'true'
128
133
  post_install_message:
129
134
  rdoc_options: []
130
135
  require_paths:
@@ -133,14 +138,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
138
  requirements:
134
139
  - - ">="
135
140
  - !ruby/object:Gem::Version
136
- version: '2.2'
141
+ version: '2.4'
137
142
  required_rubygems_version: !ruby/object:Gem::Requirement
138
143
  requirements:
139
144
  - - ">="
140
145
  - !ruby/object:Gem::Version
141
146
  version: '0'
142
147
  requirements: []
143
- rubygems_version: 3.2.26
148
+ rubygems_version: 3.5.3
144
149
  signing_key:
145
150
  specification_version: 4
146
151
  summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
@@ -1,26 +0,0 @@
1
- class ClosedQueueError < StandardError; end
2
- module Puma
3
-
4
- # Queue#close was added in Ruby 2.3.
5
- # Add a simple implementation for earlier Ruby versions.
6
- #
7
- module QueueClose
8
- def close
9
- num_waiting.times {push nil}
10
- @closed = true
11
- end
12
- def closed?
13
- @closed ||= false
14
- end
15
- def push(object)
16
- raise ClosedQueueError if closed?
17
- super
18
- end
19
- alias << push
20
- def pop(non_block=false)
21
- return nil if !non_block && closed? && empty?
22
- super
23
- end
24
- end
25
- ::Queue.prepend QueueClose
26
- end
data/lib/puma/systemd.rb DELETED
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'sd_notify'
4
-
5
- module Puma
6
- class Systemd
7
- def initialize(events)
8
- @events = events
9
- end
10
-
11
- def hook_events
12
- @events.on_booted { SdNotify.ready }
13
- @events.on_stopped { SdNotify.stopping }
14
- @events.on_restart { SdNotify.reloading }
15
- end
16
-
17
- def start_watchdog
18
- return unless SdNotify.watchdog?
19
-
20
- ping_f = watchdog_sleep_time
21
-
22
- log "Pinging systemd watchdog every #{ping_f.round(1)} sec"
23
- Thread.new do
24
- loop do
25
- sleep ping_f
26
- SdNotify.watchdog
27
- end
28
- end
29
- end
30
-
31
- private
32
-
33
- def watchdog_sleep_time
34
- usec = Integer(ENV["WATCHDOG_USEC"])
35
-
36
- sec_f = usec / 1_000_000.0
37
- # "It is recommended that a daemon sends a keep-alive notification message
38
- # to the service manager every half of the time returned here."
39
- sec_f / 2
40
- end
41
-
42
- def log(str)
43
- @events.log str
44
- end
45
- end
46
- end