Skip to content

Commit 5a7d884

Browse files
authored
Merge pull request #1579 from puma/schneems/waiting
[close #1577] Negative Backpressure Metric
2 parents e4255d0 + ae5c94f commit 5a7d884

5 files changed

Lines changed: 25 additions & 7 deletions

File tree

lib/puma/cluster.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,8 @@ def worker(index, master)
292292
begin
293293
b = server.backlog || 0
294294
r = server.running || 0
295-
payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r} }\n!
295+
t = server.pool_capacity || 0
296+
payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r}, "pool_capacity":#{t} }\n!
296297
io << payload
297298
rescue IOError
298299
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue

lib/puma/server.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,18 @@ def running
168168
@thread_pool and @thread_pool.spawned
169169
end
170170

171+
172+
# This number represents the number of requests that
173+
# the server is capable of taking right now.
174+
#
175+
# For example if the number is 5 then it means
176+
# there are 5 threads sitting idle ready to take
177+
# a request. If one request comes in, then the
178+
# value would be 4 until it finishes processing.
179+
def pool_capacity
180+
@thread_pool and @thread_pool.pool_capacity
181+
end
182+
171183
# Lopez Mode == raw tcp apps
172184

173185
def run_lopez_mode(background=true)

lib/puma/single.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ class Single < Runner
1414
def stats
1515
b = @server.backlog || 0
1616
r = @server.running || 0
17-
%Q!{ "backlog": #{b}, "running": #{r} }!
17+
t = @server.pool_capacity || 0
18+
%Q!{ "backlog": #{b}, "running": #{r}, "pool_capacity": #{t} }!
1819
end
1920

2021
def restart

lib/puma/thread_pool.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def initialize(min, max, *extra, &block)
5858
@clean_thread_locals = false
5959
end
6060

61-
attr_reader :spawned, :trim_requested
61+
attr_reader :spawned, :trim_requested, :waiting
6262
attr_accessor :clean_thread_locals
6363

6464
def self.clean_thread_locals
@@ -73,6 +73,10 @@ def backlog
7373
@mutex.synchronize { @todo.size }
7474
end
7575

76+
def pool_capacity
77+
waiting + (@max - spawned)
78+
end
79+
7680
# :nodoc:
7781
#
7882
# Must be called with @mutex held!

test/test_cli.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ def test_control_for_tcp
5656
s = TCPSocket.new "127.0.0.1", 9877
5757
s << "GET /stats HTTP/1.0\r\n\r\n"
5858
body = s.read
59-
assert_equal '{ "backlog": 0, "running": 0 }', body.split(/\r?\n/).last
60-
assert_equal '{ "backlog": 0, "running": 0 }', Puma.stats
59+
assert_equal '{ "backlog": 0, "running": 0, "pool_capacity": 16 }', body.split(/\r?\n/).last
60+
assert_equal '{ "backlog": 0, "running": 0, "pool_capacity": 16 }', Puma.stats
6161

6262
cli.launcher.stop
6363
t.join
@@ -95,7 +95,7 @@ def test_control_clustered
9595
s = UNIXSocket.new @tmp_path
9696
s << "GET /stats HTTP/1.0\r\n\r\n"
9797
body = s.read
98-
assert_match(/\{ "workers": 2, "phase": 0, "booted_workers": 2, "old_workers": 0, "worker_status": \[\{ "pid": \d+, "index": 0, "phase": 0, "booted": true, "last_checkin": "[^"]+", "last_status": \{ "backlog":0, "running":2 \} \},\{ "pid": \d+, "index": 1, "phase": 0, "booted": true, "last_checkin": "[^"]+", "last_status": \{ "backlog":0, "running":2 \} \}\] \}/, body.split("\r\n").last)
98+
assert_match(/\{ "workers": 2, "phase": 0, "booted_workers": 2, "old_workers": 0, "worker_status": \[\{ "pid": \d+, "index": 0, "phase": 0, "booted": true, "last_checkin": "[^"]+", "last_status": \{ "backlog":0, "running":2, "pool_capacity":2 \} \},\{ "pid": \d+, "index": 1, "phase": 0, "booted": true, "last_checkin": "[^"]+", "last_status": \{ "backlog":0, "running":2, "pool_capacity":2 \} \}\] \}/, body.split("\r\n").last)
9999

100100
cli.launcher.stop
101101
t.join
@@ -118,7 +118,7 @@ def test_control
118118
s << "GET /stats HTTP/1.0\r\n\r\n"
119119
body = s.read
120120

121-
assert_equal '{ "backlog": 0, "running": 0 }', body.split("\r\n").last
121+
assert_equal '{ "backlog": 0, "running": 0, "pool_capacity": 16 }', body.split("\r\n").last
122122

123123
cli.launcher.stop
124124
t.join

0 commit comments

Comments
 (0)