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.
@@ -25,6 +25,8 @@ module Puma
25
25
  # up its work before leaving the thread to die on the vine.
26
26
  SHUTDOWN_GRACE_TIME = 5 # seconds
27
27
 
28
+ attr_reader :out_of_band_running
29
+
28
30
  # Maintain a minimum of +min+ and maximum of +max+ threads
29
31
  # in the pool.
30
32
  #
@@ -35,9 +37,9 @@ module Puma
35
37
  @not_empty = ConditionVariable.new
36
38
  @not_full = ConditionVariable.new
37
39
  @mutex = Mutex.new
40
+ @todo = Queue.new
38
41
 
39
- @todo = []
40
-
42
+ @backlog_max = 0
41
43
  @spawned = 0
42
44
  @waiting = 0
43
45
 
@@ -50,7 +52,7 @@ module Puma
50
52
  @shutdown_grace_time = Float(options[:pool_shutdown_grace_time] || SHUTDOWN_GRACE_TIME)
51
53
  @block = block
52
54
  @out_of_band = options[:out_of_band]
53
- @clean_thread_locals = options[:clean_thread_locals]
55
+ @out_of_band_running = false
54
56
  @before_thread_start = options[:before_thread_start]
55
57
  @before_thread_exit = options[:before_thread_exit]
56
58
  @reaping_time = options[:reaping_time]
@@ -79,30 +81,37 @@ module Puma
79
81
 
80
82
  attr_reader :spawned, :trim_requested, :waiting
81
83
 
82
- def self.clean_thread_locals
83
- Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods
84
- Thread.current[key] = nil unless key == :__recursive_key__
85
- end
86
- end
87
-
88
84
  # generate stats hash so as not to perform multiple locks
89
85
  # @return [Hash] hash containing stat info from ThreadPool
90
86
  def stats
91
87
  with_mutex do
88
+ temp = @backlog_max
89
+ @backlog_max = 0
92
90
  { backlog: @todo.size,
93
91
  running: @spawned,
94
92
  pool_capacity: @waiting + (@max - @spawned),
95
- busy_threads: @spawned - @waiting + @todo.size
93
+ busy_threads: @spawned - @waiting + @todo.size,
94
+ backlog_max: temp
96
95
  }
97
96
  end
98
97
  end
99
98
 
99
+ def reset_max
100
+ with_mutex { @backlog_max = 0 }
101
+ end
102
+
100
103
  # How many objects have yet to be processed by the pool?
101
104
  #
102
105
  def backlog
103
106
  with_mutex { @todo.size }
104
107
  end
105
108
 
109
+ # The maximum size of the backlog
110
+ #
111
+ def backlog_max
112
+ with_mutex { @backlog_max }
113
+ end
114
+
106
115
  # @!attribute [r] pool_capacity
107
116
  def pool_capacity
108
117
  waiting + (@max - spawned)
@@ -159,10 +168,6 @@ module Puma
159
168
  work = todo.shift
160
169
  end
161
170
 
162
- if @clean_thread_locals
163
- ThreadPool.clean_thread_locals
164
- end
165
-
166
171
  begin
167
172
  @out_of_band_pending = true if block.call(work)
168
173
  rescue Exception => e
@@ -183,7 +188,7 @@ module Puma
183
188
 
184
189
  @before_thread_start.each do |b|
185
190
  begin
186
- b.call
191
+ b[:block].call
187
192
  rescue Exception => e
188
193
  STDERR.puts "WARNING before_thread_start hook failed with exception (#{e.class}) #{e.message}"
189
194
  end
@@ -198,7 +203,7 @@ module Puma
198
203
 
199
204
  @before_thread_exit.each do |b|
200
205
  begin
201
- b.call
206
+ b[:block].call
202
207
  rescue Exception => e
203
208
  STDERR.puts "WARNING before_thread_exit hook failed with exception (#{e.class}) #{e.message}"
204
209
  end
@@ -214,12 +219,14 @@ module Puma
214
219
 
215
220
  # we execute on idle hook when all threads are free
216
221
  return false unless @spawned == @waiting
217
-
218
- @out_of_band.each(&:call)
222
+ @out_of_band_running = true
223
+ @out_of_band.each { |b| b[:block].call }
219
224
  true
220
225
  rescue Exception => e
221
226
  STDERR.puts "Exception calling out_of_band_hook: #{e.message} (#{e.class})"
222
227
  true
228
+ ensure
229
+ @out_of_band_running = false
223
230
  end
224
231
 
225
232
  private :trigger_out_of_band_hook
@@ -239,6 +246,8 @@ module Puma
239
246
  end
240
247
 
241
248
  @todo << work
249
+ t = @todo.size
250
+ @backlog_max = t if t > @backlog_max
242
251
 
243
252
  if @waiting < @todo.size and @spawned < @max
244
253
  spawn_thread
@@ -248,69 +257,6 @@ module Puma
248
257
  end
249
258
  end
250
259
 
251
- # This method is used by `Puma::Server` to let the server know when
252
- # the thread pool can pull more requests from the socket and
253
- # pass to the reactor.
254
- #
255
- # The general idea is that the thread pool can only work on a fixed
256
- # number of requests at the same time. If it is already processing that
257
- # number of requests then it is at capacity. If another Puma process has
258
- # spare capacity, then the request can be left on the socket so the other
259
- # worker can pick it up and process it.
260
- #
261
- # For example: if there are 5 threads, but only 4 working on
262
- # requests, this method will not wait and the `Puma::Server`
263
- # can pull a request right away.
264
- #
265
- # If there are 5 threads and all 5 of them are busy, then it will
266
- # pause here, and wait until the `not_full` condition variable is
267
- # signaled, usually this indicates that a request has been processed.
268
- #
269
- # It's important to note that even though the server might accept another
270
- # request, it might not be added to the `@todo` array right away.
271
- # For example if a slow client has only sent a header, but not a body
272
- # then the `@todo` array would stay the same size as the reactor works
273
- # to try to buffer the request. In that scenario the next call to this
274
- # method would not block and another request would be added into the reactor
275
- # by the server. This would continue until a fully buffered request
276
- # makes it through the reactor and can then be processed by the thread pool.
277
- def wait_until_not_full
278
- with_mutex do
279
- while true
280
- return if @shutdown
281
-
282
- # If we can still spin up new threads and there
283
- # is work queued that cannot be handled by waiting
284
- # threads, then accept more work until we would
285
- # spin up the max number of threads.
286
- return if busy_threads < @max
287
-
288
- @not_full.wait @mutex
289
- end
290
- end
291
- end
292
-
293
- # @version 5.0.0
294
- def wait_for_less_busy_worker(delay_s)
295
- return unless delay_s && delay_s > 0
296
-
297
- # Ruby MRI does GVL, this can result
298
- # in processing contention when multiple threads
299
- # (requests) are running concurrently
300
- return unless Puma.mri?
301
-
302
- with_mutex do
303
- return if @shutdown
304
-
305
- # do not delay, if we are not busy
306
- return unless busy_threads > 0
307
-
308
- # this will be signaled once a request finishes,
309
- # which can happen earlier than delay
310
- @not_full.wait @mutex, delay_s
311
- end
312
- end
313
-
314
260
  # If there are any free threads in the pool, tell one to go ahead
315
261
  # and exit. If +force+ is true, then a trim request is requested
316
262
  # even if all threads are being utilized.
data/lib/puma/util.rb CHANGED
@@ -10,13 +10,6 @@ module Puma
10
10
  IO.pipe
11
11
  end
12
12
 
13
- # An instance method on Thread has been provided to address https://bugs.ruby-lang.org/issues/13632,
14
- # which currently affects some older versions of Ruby: 2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1
15
- # Additional context: https://github.com/puma/puma/pull/1345
16
- def purge_interrupt_queue
17
- Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
18
- end
19
-
20
13
  # Escapes and unescapes a URI escaped string with
21
14
  # +encoding+. +encoding+ will be the target encoding of the string
22
15
  # returned, and it defaults to UTF-8
data/lib/puma.rb CHANGED
@@ -75,4 +75,14 @@ module Puma
75
75
  def self.set_thread_name(name)
76
76
  Thread.current.name = "puma #{name}"
77
77
  end
78
+
79
+ # Shows deprecated warning for renamed methods.
80
+ # @example
81
+ # Puma.deprecate_method_change :on_booted, __callee__, __method__
82
+ #
83
+ def self.deprecate_method_change(method_old, method_caller, method_new)
84
+ if method_old == method_caller
85
+ warn "Use '#{method_new}', '#{method_caller}' is deprecated and will be removed in v8"
86
+ end
87
+ end
78
88
  end
@@ -32,7 +32,7 @@ module Puma
32
32
 
33
33
  @events = options[:events] || ::Puma::Events.new
34
34
 
35
- conf = ::Puma::Configuration.new(options, default_options.merge({events: @events})) do |user_config, file_config, default_config|
35
+ conf = ::Puma::Configuration.new(options, default_options.merge({ events: @events })) do |user_config, file_config, default_config|
36
36
  if options.delete(:Verbose)
37
37
  begin
38
38
  require 'rack/commonlogger' # Rack 1.x
@@ -72,7 +72,7 @@ module Puma
72
72
 
73
73
  log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
74
74
 
75
- launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer, events: @events)
75
+ launcher = ::Puma::Launcher.new(conf, log_writer: log_writer, events: @events)
76
76
 
77
77
  yield launcher if block_given?
78
78
  begin
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.6.1
4
+ version: 7.0.0
5
5
  platform: java
6
6
  authors:
7
7
  - Evan Phoenix
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
10
+ date: 2025-09-03 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  requirement: !ruby/object:Gem::Requirement
@@ -138,14 +138,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
138
  requirements:
139
139
  - - ">="
140
140
  - !ruby/object:Gem::Version
141
- version: '2.4'
141
+ version: '3.0'
142
142
  required_rubygems_version: !ruby/object:Gem::Requirement
143
143
  requirements:
144
144
  - - ">="
145
145
  - !ruby/object:Gem::Version
146
146
  version: '0'
147
147
  requirements: []
148
- rubygems_version: 3.6.9
148
+ rubygems_version: 3.6.3
149
149
  specification_version: 4
150
150
  summary: A Ruby/Rack web server built for parallelism.
151
151
  test_files: []