puma 6.5.0-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 +43 -2
- data/README.md +9 -1
- data/docs/fork_worker.md +7 -1
- data/docs/java_options.md +6 -0
- data/docs/plugins.md +4 -0
- data/docs/stats.md +6 -2
- data/ext/puma_http11/org/jruby/puma/Http11.java +1 -1
- data/ext/puma_http11/puma_http11.c +1 -1
- data/lib/puma/app/status.rb +1 -1
- data/lib/puma/binder.rb +7 -0
- data/lib/puma/cluster/worker.rb +9 -6
- data/lib/puma/cluster/worker_handle.rb +1 -1
- data/lib/puma/cluster.rb +12 -8
- data/lib/puma/configuration.rb +2 -0
- data/lib/puma/const.rb +10 -9
- data/lib/puma/dsl.rb +30 -10
- data/lib/puma/launcher.rb +14 -5
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/runner.rb +4 -1
- data/lib/puma/sd_notify.rb +1 -4
- data/lib/puma/server.rb +9 -5
- data/lib/puma/thread_pool.rb +4 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dfd1231ff4cb015039008033048363558383da83f699e7b20035c0a0ad62a50
|
4
|
+
data.tar.gz: f1163c39e8cf7374c7b777140e5ddf8cd7427f44178f4f5257154dab3307992f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30bf816517a7a65d268917f6f996a9f889a12e911db48373818a94ad808011269534d46555316d602462539ac732beb2c7f1f58e8f8f032c58c72aaab9d52706
|
7
|
+
data.tar.gz: b226ba82ffd6027d51ad5e63dadfca776a56e685f5b6583b815815aab69cb79aaf27b4c06e81021f15a75691aedf75fca7dc017df2f5bf913965aa635e989627
|
data/History.md
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
## 6.6.0 / 2025-01-29
|
2
|
+
|
3
|
+
* Features
|
4
|
+
* Option to turn off SIGUSR2 trapping ([#3570], [#3567])
|
5
|
+
* Shorten `ThreadPool` trimmer and reaper thread names ([#3383])
|
6
|
+
* Add after_refork hook ([#3386])
|
7
|
+
* Add busy threads stat ([#3517])
|
8
|
+
* Add a debug log before running each type of hook ([#3375])
|
9
|
+
* Allow alternative schemes in Binder ([#3348], [#3302])
|
10
|
+
* Avoid spawning `Threadpool#trim` thread if pool size is fixed ([#3384])
|
11
|
+
|
12
|
+
* Bugfixes
|
13
|
+
* Change `HttpParserError` to be subclass of `StandardError` ([#3590], [#3552])
|
14
|
+
* added test cases
|
15
|
+
* fix update phased restart symlink folder
|
16
|
+
|
17
|
+
* Performance
|
18
|
+
* Only ping worker 0 during phased restart if using fork worker ([#3568])
|
19
|
+
|
20
|
+
* Refactor
|
21
|
+
* Fix multi-delimiter split to get status app token ([#3505])
|
22
|
+
* Change ping to use const ([#3595])
|
23
|
+
* Fixup use of Puma::Const::PipeRequest constants ([#3565])
|
24
|
+
* Update DSL hook processing logic to be consistent ([#3376])
|
25
|
+
|
1
26
|
## 6.5.0 / 2024-11-23
|
2
27
|
|
3
28
|
* Features
|
@@ -2125,6 +2150,22 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
2125
2150
|
* Bugfixes
|
2126
2151
|
* Your bugfix goes here <Most recent on the top, like GitHub> (#Github Number)
|
2127
2152
|
|
2153
|
+
[#3570]:https://github.com/puma/puma/pull/3570 "PR by @mohamedhafez, merged 2024-12-30"
|
2154
|
+
[#3567]:https://github.com/puma/puma/issues/3567 "Issue by @mohamedhafez, closed 2024-12-30"
|
2155
|
+
[#3383]:https://github.com/puma/puma/pull/3383 "PR by @joshuay03, merged 2024-11-29"
|
2156
|
+
[#3386]:https://github.com/puma/puma/pull/3386 "PR by @Drakula2k, merged 2024-11-27"
|
2157
|
+
[#3517]:https://github.com/puma/puma/pull/3517 "PR by @jjb, merged 2024-11-26"
|
2158
|
+
[#3375]:https://github.com/puma/puma/pull/3375 "PR by @joshuay03, merged 2024-11-23"
|
2159
|
+
[#3348]:https://github.com/puma/puma/pull/3348 "PR by @tomurb, merged 2024-11-23"
|
2160
|
+
[#3302]:https://github.com/puma/puma/issues/3302 "Issue by @benburkert, closed 2024-11-23"
|
2161
|
+
[#3384]:https://github.com/puma/puma/pull/3384 "PR by @joshuay03, merged 2024-11-23"
|
2162
|
+
[#3590]:https://github.com/puma/puma/pull/3590 "PR by @MSP-Greg, merged 2025-01-01"
|
2163
|
+
[#3552]:https://github.com/puma/puma/issues/3552 "Issue by @utay, closed 2025-01-01"
|
2164
|
+
[#3568]:https://github.com/puma/puma/pull/3568 "PR by @joshuay03, merged 2024-12-11"
|
2165
|
+
[#3505]:https://github.com/puma/puma/pull/3505 "PR by @AnthonyClark, merged 2025-01-27"
|
2166
|
+
[#3595]:https://github.com/puma/puma/pull/3595 "PR by @nateberkopec, merged 2025-01-07"
|
2167
|
+
[#3565]:https://github.com/puma/puma/pull/3565 "PR by @MSP-Greg, merged 2024-11-28"
|
2168
|
+
[#3376]:https://github.com/puma/puma/pull/3376 "PR by @joshuay03, merged 2024-11-23"
|
2128
2169
|
[#3407]:https://github.com/puma/puma/pull/3407 "PR by @JacobEvelyn, merged 2024-11-05"
|
2129
2170
|
[#3439]:https://github.com/puma/puma/pull/3439 "PR by @codergeek121, merged 2024-11-04"
|
2130
2171
|
[#3437]:https://github.com/puma/puma/issues/3437 "Issue by @rafaelfranca, closed 2024-11-04"
|
@@ -2709,14 +2750,14 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
2709
2750
|
[#782]:https://github.com/puma/puma/issues/782 "Issue by @Tonkpils, closed 2016-07-19"
|
2710
2751
|
[#1010]:https://github.com/puma/puma/issues/1010 "Issue by @mneumark, closed 2016-07-19"
|
2711
2752
|
[#959]:https://github.com/puma/puma/issues/959 "Issue by @mwpastore, closed 2016-04-22"
|
2712
|
-
[#840]:https://github.com/puma/puma/issues/840 "Issue by @
|
2753
|
+
[#840]:https://github.com/puma/puma/issues/840 "Issue by @marisawallace, closed 2016-04-07"
|
2713
2754
|
[#1007]:https://github.com/puma/puma/pull/1007 "PR by @willnet, merged 2016-06-24"
|
2714
2755
|
[#1014]:https://github.com/puma/puma/pull/1014 "PR by @szymon-jez, merged 2016-07-11"
|
2715
2756
|
[#1015]:https://github.com/puma/puma/pull/1015 "PR by @bf4, merged 2016-07-19"
|
2716
2757
|
[#1017]:https://github.com/puma/puma/pull/1017 "PR by @jorihardman, merged 2016-07-19"
|
2717
2758
|
[#954]:https://github.com/puma/puma/pull/954 "PR by @jf, merged 2016-04-12"
|
2718
2759
|
[#955]:https://github.com/puma/puma/pull/955 "PR by @jf, merged 2016-04-22"
|
2719
|
-
[#956]:https://github.com/puma/puma/pull/956 "PR by @
|
2760
|
+
[#956]:https://github.com/puma/puma/pull/956 "PR by @marisawallace, merged 2016-04-12"
|
2720
2761
|
[#960]:https://github.com/puma/puma/pull/960 "PR by @kmayer, merged 2016-04-15"
|
2721
2762
|
[#969]:https://github.com/puma/puma/pull/969 "PR by @frankwong15, merged 2016-05-10"
|
2722
2763
|
[#970]:https://github.com/puma/puma/pull/970 "PR by @willnet, merged 2016-04-26"
|
data/README.md
CHANGED
@@ -159,7 +159,7 @@ on_worker_boot do
|
|
159
159
|
end
|
160
160
|
```
|
161
161
|
|
162
|
-
In addition, there is an `on_refork`
|
162
|
+
In addition, there is an `on_refork` and `after_refork` hooks which are used only in [`fork_worker` mode](docs/fork_worker.md),
|
163
163
|
when the worker 0 child process forks a grandchild worker:
|
164
164
|
|
165
165
|
```ruby
|
@@ -169,6 +169,13 @@ on_refork do
|
|
169
169
|
end
|
170
170
|
```
|
171
171
|
|
172
|
+
```ruby
|
173
|
+
after_refork do
|
174
|
+
# Used only when fork_worker mode is enabled. Add code to run inside the Puma worker 0
|
175
|
+
# child process after it forks a grandchild worker.
|
176
|
+
end
|
177
|
+
```
|
178
|
+
|
172
179
|
Importantly, note the following considerations when Ruby forks a child process:
|
173
180
|
|
174
181
|
1. File descriptors such as network sockets **are** copied from the parent to the forked
|
@@ -186,6 +193,7 @@ Therefore, we recommend the following:
|
|
186
193
|
2. If (1) is not possible, use `before_fork` and `on_refork` to disconnect the parent's socket
|
187
194
|
connections when forking, so that they are not accidentally copied to the child process.
|
188
195
|
3. Use `on_worker_boot` to restart any background threads on the forked child.
|
196
|
+
4. Use `after_refork` to restart any background threads on the parent.
|
189
197
|
|
190
198
|
#### Master process lifecycle hooks
|
191
199
|
|
data/docs/fork_worker.md
CHANGED
@@ -24,7 +24,13 @@ The `fork_worker` option allows your application to be initialized only once for
|
|
24
24
|
|
25
25
|
### Usage Considerations
|
26
26
|
|
27
|
-
- `fork_worker` introduces
|
27
|
+
- `fork_worker` introduces new `on_refork` and `after_refork` configuration hooks. Note the following:
|
28
|
+
- When initially forking the parent process to the worker 0 child, `before_fork` will trigger on the parent process and `on_worker_boot` will trigger on the worker 0 child as normal.
|
29
|
+
- When forking the worker 0 child to grandchild workers, `on_refork` and `after_refork` will trigger on the worker 0 child, and `on_worker_boot` will trigger on each grandchild worker.
|
30
|
+
- For clarity, `before_fork` does not trigger on worker 0, and `after_refork` does not trigger on the grandchild.
|
31
|
+
- As a general migration guide:
|
32
|
+
- Copy any logic within your existing `before_fork` hook to the `on_refork` hook.
|
33
|
+
- Consider to copy logic from your `on_worker_boot` hook to the `after_refork` hook, if it is needed to reset the state of worker 0 after it forks.
|
28
34
|
|
29
35
|
### Limitations
|
30
36
|
|
data/docs/java_options.md
CHANGED
@@ -12,6 +12,7 @@ Moreover, default values may be used in case of invalid inputs.
|
|
12
12
|
| PUMA_QUERY_STRING_MAX_LENGTH | 1024 * 10 | Positive natural number |
|
13
13
|
| PUMA_REQUEST_PATH_MAX_LENGTH | 8192 | Positive natural number |
|
14
14
|
| PUMA_REQUEST_URI_MAX_LENGTH | 1024 * 12 | Positive natural number |
|
15
|
+
| PUMA_SKIP_SIGUSR2 | nil | n/a |
|
15
16
|
|
16
17
|
## Examples
|
17
18
|
|
@@ -46,3 +47,8 @@ foo@bar:~ curl "http://localhost:9292${path}"
|
|
46
47
|
Hello World
|
47
48
|
```
|
48
49
|
|
50
|
+
### Java Flight Recorder Compatibility
|
51
|
+
|
52
|
+
Unfortunately Java Flight Recorder uses `SIGUSR2` internally. If you wish to
|
53
|
+
use JFR, turn off Puma's trapping of `SIGUSR2` by setting the environment variable
|
54
|
+
`PUMA_SKIP_SIGUSR2` to any value.
|
data/docs/plugins.md
CHANGED
@@ -36,3 +36,7 @@ object that is useful for additional configuration.
|
|
36
36
|
|
37
37
|
Public methods in [`Puma::Plugin`](../lib/puma/plugin.rb) are treated as a
|
38
38
|
public API for plugins.
|
39
|
+
|
40
|
+
## Binder hooks
|
41
|
+
|
42
|
+
There's `Puma::Binder#before_parse` method that allows to add proc to run before the body of `Puma::Binder#parse`. Example of usage can be found in [that repository](https://github.com/anchordotdev/puma-acme/blob/v0.1.3/lib/puma/acme/plugin.rb#L97-L118) (`before_parse_hook` could be renamed `before_parse`, making monkey patching of [binder.rb](https://github.com/anchordotdev/puma-acme/blob/v0.1.3/lib/puma/acme/binder.rb) is unnecessary).
|
data/docs/stats.md
CHANGED
@@ -55,10 +55,14 @@ end
|
|
55
55
|
|
56
56
|
When Puma runs in single mode, these stats are available at the top level. When Puma runs in cluster mode, these stats are available within the `worker_status` array in a hash labeled `last_status`, in an array of hashes where one hash represents each worker.
|
57
57
|
|
58
|
-
* backlog: requests that are waiting for an available thread to be available. if this is above 0, you need more capacity
|
58
|
+
* backlog: requests that are waiting for an available thread to be available. if this is frequently above 0, you need more capacity.
|
59
59
|
* running: how many threads are spawned. A spawned thread may be busy processing a request or waiting for a new request. If `min_threads` and `max_threads` are set to the same number,
|
60
60
|
this will be a never-changing number (other than rare cases when a thread dies, etc).
|
61
|
-
*
|
61
|
+
* busy_threads: `running` - `how many threads are waiting to receive work` + `how many requests are waiting for a thread to pick them up`.
|
62
|
+
this is a "wholistic" stat reflecting the overall current state of work to be done and the capacity to do it.
|
63
|
+
* pool_capacity: `how many threads are waiting to receive work` + `max_threads` - `running`. In a typical configuration where `min_threads`
|
64
|
+
and `max_threads` are configured to the same number, this is simply `how many threads are waiting to receive work`. This number exists only as a stat
|
65
|
+
and is not used for any internal decisions, unlike `busy_theads`, which is usually a more useful stat.
|
62
66
|
* max_threads: the maximum number of threads Puma is configured to spool per worker
|
63
67
|
* requests_count: the number of requests this worker has served since starting
|
64
68
|
|
@@ -77,7 +77,7 @@ public class Http11 extends RubyObject {
|
|
77
77
|
|
78
78
|
public static void createHttp11(Ruby runtime) {
|
79
79
|
RubyModule mPuma = runtime.defineModule("Puma");
|
80
|
-
mPuma.defineClassUnder("HttpParserError",runtime.getClass("
|
80
|
+
mPuma.defineClassUnder("HttpParserError",runtime.getClass("StandardError"),runtime.getClass("StandardError").getAllocator());
|
81
81
|
|
82
82
|
RubyClass cHttpParser = mPuma.defineClassUnder("HttpParser",runtime.getObject(),ALLOCATOR);
|
83
83
|
cHttpParser.defineAnnotatedMethods(Http11.class);
|
@@ -475,7 +475,7 @@ void Init_puma_http11(void)
|
|
475
475
|
DEF_GLOBAL(server_protocol, "SERVER_PROTOCOL");
|
476
476
|
DEF_GLOBAL(request_path, "REQUEST_PATH");
|
477
477
|
|
478
|
-
eHttpParserError = rb_define_class_under(mPuma, "HttpParserError",
|
478
|
+
eHttpParserError = rb_define_class_under(mPuma, "HttpParserError", rb_eStandardError);
|
479
479
|
rb_global_variable(&eHttpParserError);
|
480
480
|
|
481
481
|
rb_define_alloc_func(cHttpParser, HttpParser_alloc);
|
data/lib/puma/app/status.rb
CHANGED
@@ -80,7 +80,7 @@ module Puma
|
|
80
80
|
|
81
81
|
def authenticate(env)
|
82
82
|
return true unless @auth_token
|
83
|
-
env['QUERY_STRING'].to_s.split(
|
83
|
+
env['QUERY_STRING'].to_s.split(/[&;]/).include? "token=#{@auth_token}"
|
84
84
|
end
|
85
85
|
|
86
86
|
def rack_response(status, body, content_type='application/json')
|
data/lib/puma/binder.rb
CHANGED
@@ -142,7 +142,14 @@ module Puma
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
+
def before_parse(&block)
|
146
|
+
@before_parse ||= []
|
147
|
+
@before_parse << block if block
|
148
|
+
@before_parse
|
149
|
+
end
|
150
|
+
|
145
151
|
def parse(binds, log_writer = nil, log_msg = 'Listening')
|
152
|
+
before_parse.each(&:call)
|
146
153
|
log_writer ||= @log_writer
|
147
154
|
binds.each do |str|
|
148
155
|
uri = URI.parse str
|
data/lib/puma/cluster/worker.rb
CHANGED
@@ -88,25 +88,27 @@ module Puma
|
|
88
88
|
server.begin_restart(true)
|
89
89
|
@config.run_hooks(:before_refork, nil, @log_writer, @hook_data)
|
90
90
|
end
|
91
|
+
elsif idx == -2 # refork cycle is done
|
92
|
+
@config.run_hooks(:after_refork, nil, @log_writer, @hook_data)
|
91
93
|
elsif idx == 0 # restart server
|
92
94
|
restart_server << true << false
|
93
95
|
else # fork worker
|
94
96
|
worker_pids << pid = spawn_worker(idx)
|
95
|
-
@worker_write << "#{
|
97
|
+
@worker_write << "#{PIPE_FORK}#{pid}:#{idx}\n" rescue nil
|
96
98
|
end
|
97
99
|
end
|
98
100
|
end
|
99
101
|
end
|
100
102
|
|
101
103
|
Signal.trap "SIGTERM" do
|
102
|
-
@worker_write << "#{
|
104
|
+
@worker_write << "#{PIPE_EXTERNAL_TERM}#{Process.pid}\n" rescue nil
|
103
105
|
restart_server.clear
|
104
106
|
server.stop
|
105
107
|
restart_server << false
|
106
108
|
end
|
107
109
|
|
108
110
|
begin
|
109
|
-
@worker_write << "#{
|
111
|
+
@worker_write << "#{PIPE_BOOT}#{Process.pid}:#{index}\n"
|
110
112
|
rescue SystemCallError, IOError
|
111
113
|
Puma::Util.purge_interrupt_queue
|
112
114
|
STDERR.puts "Master seems to have exited, exiting."
|
@@ -122,7 +124,7 @@ module Puma
|
|
122
124
|
|
123
125
|
stat_thread ||= Thread.new(@worker_write) do |io|
|
124
126
|
Puma.set_thread_name "stat pld"
|
125
|
-
base_payload = "
|
127
|
+
base_payload = "#{PIPE_PING}#{Process.pid}"
|
126
128
|
|
127
129
|
while true
|
128
130
|
begin
|
@@ -131,7 +133,8 @@ module Puma
|
|
131
133
|
t = server.pool_capacity || 0
|
132
134
|
m = server.max_threads || 0
|
133
135
|
rc = server.requests_count || 0
|
134
|
-
|
136
|
+
bt = server.busy_threads || 0
|
137
|
+
payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r}, "pool_capacity":#{t}, "max_threads":#{m}, "requests_count":#{rc}, "busy_threads":#{bt} }\n!
|
135
138
|
io << payload
|
136
139
|
rescue IOError
|
137
140
|
Puma::Util.purge_interrupt_queue
|
@@ -147,7 +150,7 @@ module Puma
|
|
147
150
|
# exiting until any background operations are completed
|
148
151
|
@config.run_hooks(:before_worker_shutdown, index, @log_writer, @hook_data)
|
149
152
|
ensure
|
150
|
-
@worker_write << "#{
|
153
|
+
@worker_write << "#{PIPE_TERM}#{Process.pid}\n" rescue nil
|
151
154
|
@worker_write.close
|
152
155
|
end
|
153
156
|
|
@@ -51,7 +51,7 @@ module Puma
|
|
51
51
|
@term
|
52
52
|
end
|
53
53
|
|
54
|
-
STATUS_PATTERN = /{ "backlog":(?<backlog>\d*), "running":(?<running>\d*), "pool_capacity":(?<pool_capacity>\d*), "max_threads":(?<max_threads>\d*), "requests_count":(?<requests_count>\d*) }/
|
54
|
+
STATUS_PATTERN = /{ "backlog":(?<backlog>\d*), "running":(?<running>\d*), "pool_capacity":(?<pool_capacity>\d*), "max_threads":(?<max_threads>\d*), "requests_count":(?<requests_count>\d*), "busy_threads":(?<busy_threads>\d*) }/
|
55
55
|
private_constant :STATUS_PATTERN
|
56
56
|
|
57
57
|
def ping!(status)
|
data/lib/puma/cluster.rb
CHANGED
@@ -87,6 +87,10 @@ module Puma
|
|
87
87
|
|
88
88
|
if @options[:fork_worker] && all_workers_in_phase?
|
89
89
|
@fork_writer << "0\n"
|
90
|
+
|
91
|
+
if worker_at(0).phase > 0
|
92
|
+
@fork_writer << "-2\n"
|
93
|
+
end
|
90
94
|
end
|
91
95
|
end
|
92
96
|
|
@@ -456,7 +460,7 @@ module Puma
|
|
456
460
|
req = read.read_nonblock(1)
|
457
461
|
next unless req
|
458
462
|
|
459
|
-
if req ==
|
463
|
+
if req == PIPE_WAKEUP
|
460
464
|
@next_check = Time.now
|
461
465
|
next
|
462
466
|
end
|
@@ -464,7 +468,7 @@ module Puma
|
|
464
468
|
result = read.gets
|
465
469
|
pid = result.to_i
|
466
470
|
|
467
|
-
if req ==
|
471
|
+
if req == PIPE_BOOT || req == PIPE_FORK
|
468
472
|
pid, idx = result.split(':').map(&:to_i)
|
469
473
|
w = worker_at idx
|
470
474
|
w.pid = pid if w.pid.nil?
|
@@ -472,22 +476,22 @@ module Puma
|
|
472
476
|
|
473
477
|
if w = @workers.find { |x| x.pid == pid }
|
474
478
|
case req
|
475
|
-
when
|
479
|
+
when PIPE_BOOT
|
476
480
|
w.boot!
|
477
481
|
log "- Worker #{w.index} (PID: #{pid}) booted in #{w.uptime.round(2)}s, phase: #{w.phase}"
|
478
482
|
@next_check = Time.now
|
479
483
|
workers_not_booted -= 1
|
480
|
-
when
|
484
|
+
when PIPE_EXTERNAL_TERM
|
481
485
|
# external term, see worker method, Signal.trap "SIGTERM"
|
482
486
|
w.term!
|
483
|
-
when
|
487
|
+
when PIPE_TERM
|
484
488
|
w.term unless w.term?
|
485
|
-
when
|
489
|
+
when PIPE_PING
|
486
490
|
status = result.sub(/^\d+/,'').chomp
|
487
491
|
w.ping!(status)
|
488
492
|
@events.fire(:ping!, w)
|
489
493
|
|
490
|
-
if in_phased_restart && workers_not_booted.positive? && w0 = worker_at(0)
|
494
|
+
if in_phased_restart && @options[:fork_worker] && workers_not_booted.positive? && w0 = worker_at(0)
|
491
495
|
w0.ping!(status)
|
492
496
|
@events.fire(:ping!, w0)
|
493
497
|
end
|
@@ -497,7 +501,7 @@ module Puma
|
|
497
501
|
debug_loaded_extensions("Loaded Extensions - master:") if @log_writer.debug?
|
498
502
|
booted = true
|
499
503
|
end
|
500
|
-
when
|
504
|
+
when PIPE_IDLE
|
501
505
|
if idle_workers[pid]
|
502
506
|
idle_workers.delete pid
|
503
507
|
else
|
data/lib/puma/configuration.rb
CHANGED
data/lib/puma/const.rb
CHANGED
@@ -100,8 +100,8 @@ module Puma
|
|
100
100
|
# too taxing on performance.
|
101
101
|
module Const
|
102
102
|
|
103
|
-
PUMA_VERSION = VERSION = "6.
|
104
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "6.6.0"
|
104
|
+
CODE_NAME = "Return to Forever"
|
105
105
|
|
106
106
|
PUMA_SERVER_STRING = ["puma", PUMA_VERSION, CODE_NAME].join(" ").freeze
|
107
107
|
|
@@ -294,14 +294,15 @@ module Puma
|
|
294
294
|
|
295
295
|
PROXY_PROTOCOL_V1_REGEX = /^PROXY (?:TCP4|TCP6|UNKNOWN) ([^\r]+)\r\n/.freeze
|
296
296
|
|
297
|
+
# All constants are prefixed with `PIPE_` to avoid name collisions.
|
297
298
|
module PipeRequest
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
299
|
+
PIPE_WAKEUP = "!"
|
300
|
+
PIPE_BOOT = "b"
|
301
|
+
PIPE_FORK = "f"
|
302
|
+
PIPE_EXTERNAL_TERM = "e"
|
303
|
+
PIPE_TERM = "t"
|
304
|
+
PIPE_PING = "p"
|
305
|
+
PIPE_IDLE = "i"
|
305
306
|
end
|
306
307
|
end
|
307
308
|
end
|
data/lib/puma/dsl.rb
CHANGED
@@ -47,6 +47,7 @@ module Puma
|
|
47
47
|
# | on_worker_boot | :before_worker_boot | inside, before |
|
48
48
|
# | on_worker_shutdown | :before_worker_shutdown | inside, after |
|
49
49
|
# | on_refork | :before_refork | inside |
|
50
|
+
# | after_refork | :after_refork | inside |
|
50
51
|
#
|
51
52
|
class DSL
|
52
53
|
ON_WORKER_KEY = [String, Symbol].freeze
|
@@ -438,8 +439,7 @@ module Puma
|
|
438
439
|
# end
|
439
440
|
#
|
440
441
|
def on_restart(&block)
|
441
|
-
|
442
|
-
@options[:on_restart] << block
|
442
|
+
process_hook :on_restart, nil, block, 'on_restart'
|
443
443
|
end
|
444
444
|
|
445
445
|
# Command to use to restart Puma. This should be just how to
|
@@ -731,8 +731,7 @@ module Puma
|
|
731
731
|
def before_fork(&block)
|
732
732
|
warn_if_in_single_mode('before_fork')
|
733
733
|
|
734
|
-
|
735
|
-
@options[:before_fork] << block
|
734
|
+
process_hook :before_fork, nil, block, 'before_fork'
|
736
735
|
end
|
737
736
|
|
738
737
|
# Code to run in a worker when it boots to setup
|
@@ -855,9 +854,32 @@ module Puma
|
|
855
854
|
# @version 5.0.0
|
856
855
|
#
|
857
856
|
def on_refork(key = nil, &block)
|
857
|
+
warn_if_in_single_mode('on_refork')
|
858
|
+
|
858
859
|
process_hook :before_refork, key, block, 'on_refork'
|
859
860
|
end
|
860
861
|
|
862
|
+
# When `fork_worker` is enabled, code to run in Worker 0
|
863
|
+
# after all other workers are re-forked from this process,
|
864
|
+
# after the server has temporarily stopped serving requests
|
865
|
+
# (once per complete refork cycle).
|
866
|
+
#
|
867
|
+
# This can be used to re-open any connections to remote servers
|
868
|
+
# (database, Redis, ...) that were closed via on_refork.
|
869
|
+
#
|
870
|
+
# This can be called multiple times to add several hooks.
|
871
|
+
#
|
872
|
+
# @note Cluster mode with `fork_worker` enabled only.
|
873
|
+
#
|
874
|
+
# @example
|
875
|
+
# after_refork do
|
876
|
+
# puts 'After refork...'
|
877
|
+
# end
|
878
|
+
#
|
879
|
+
def after_refork(key = nil, &block)
|
880
|
+
process_hook :after_refork, key, block, 'after_refork'
|
881
|
+
end
|
882
|
+
|
861
883
|
# Provide a block to be executed just before a thread is added to the thread
|
862
884
|
# pool. Be careful: while the block executes, thread creation is delayed, and
|
863
885
|
# probably a request will have to wait too! The new thread will not be added to
|
@@ -876,8 +898,7 @@ module Puma
|
|
876
898
|
# end
|
877
899
|
#
|
878
900
|
def on_thread_start(&block)
|
879
|
-
|
880
|
-
@options[:before_thread_start] << block
|
901
|
+
process_hook :before_thread_start, nil, block, 'on_thread_start'
|
881
902
|
end
|
882
903
|
|
883
904
|
# Provide a block to be executed after a thread is trimmed from the thread
|
@@ -901,8 +922,7 @@ module Puma
|
|
901
922
|
# end
|
902
923
|
#
|
903
924
|
def on_thread_exit(&block)
|
904
|
-
|
905
|
-
@options[:before_thread_exit] << block
|
925
|
+
process_hook :before_thread_exit, nil, block, 'on_thread_exit'
|
906
926
|
end
|
907
927
|
|
908
928
|
# Code to run out-of-band when the worker is idle.
|
@@ -1415,8 +1435,8 @@ module Puma
|
|
1415
1435
|
if workers_val == 0
|
1416
1436
|
log_string =
|
1417
1437
|
"Warning: You specified code to run in a `#{hook_name}` block, " \
|
1418
|
-
"but Puma is not configured to run in cluster mode (worker count > 0
|
1419
|
-
"so your `#{hook_name}` block
|
1438
|
+
"but Puma is not configured to run in cluster mode (worker count > 0), " \
|
1439
|
+
"so your `#{hook_name}` block will not run."
|
1420
1440
|
|
1421
1441
|
LogWriter.stdio.log(log_string)
|
1422
1442
|
end
|
data/lib/puma/launcher.rb
CHANGED
@@ -167,6 +167,13 @@ module Puma
|
|
167
167
|
log "* phased-restart called but not available, restarting normally."
|
168
168
|
return restart
|
169
169
|
end
|
170
|
+
|
171
|
+
if @options.file_options[:tag].nil?
|
172
|
+
dir = File.realdirpath(@restart_dir)
|
173
|
+
@options[:tag] = File.basename(dir)
|
174
|
+
set_process_title
|
175
|
+
end
|
176
|
+
|
170
177
|
true
|
171
178
|
end
|
172
179
|
|
@@ -412,12 +419,14 @@ module Puma
|
|
412
419
|
end
|
413
420
|
|
414
421
|
def setup_signals
|
415
|
-
|
416
|
-
|
417
|
-
|
422
|
+
unless ENV["PUMA_SKIP_SIGUSR2"]
|
423
|
+
begin
|
424
|
+
Signal.trap "SIGUSR2" do
|
425
|
+
restart
|
426
|
+
end
|
427
|
+
rescue Exception
|
428
|
+
log "*** SIGUSR2 not implemented, signal based restart unavailable!"
|
418
429
|
end
|
419
|
-
rescue Exception
|
420
|
-
log "*** SIGUSR2 not implemented, signal based restart unavailable!"
|
421
430
|
end
|
422
431
|
|
423
432
|
unless Puma.jruby?
|
data/lib/puma/puma_http11.jar
CHANGED
Binary file
|
data/lib/puma/runner.rb
CHANGED
@@ -8,6 +8,9 @@ module Puma
|
|
8
8
|
# serve requests. This class spawns a new instance of `Puma::Server` via
|
9
9
|
# a call to `start_server`.
|
10
10
|
class Runner
|
11
|
+
|
12
|
+
include ::Puma::Const::PipeRequest
|
13
|
+
|
11
14
|
def initialize(launcher)
|
12
15
|
@launcher = launcher
|
13
16
|
@log_writer = launcher.log_writer
|
@@ -27,7 +30,7 @@ module Puma
|
|
27
30
|
def wakeup!
|
28
31
|
return unless @wakeup
|
29
32
|
|
30
|
-
@wakeup.write
|
33
|
+
@wakeup.write PIPE_WAKEUP unless @wakeup.closed?
|
31
34
|
|
32
35
|
rescue SystemCallError, IOError
|
33
36
|
Puma::Util.purge_interrupt_queue
|
data/lib/puma/sd_notify.rb
CHANGED
@@ -137,10 +137,7 @@ module Puma
|
|
137
137
|
ENV.delete("NOTIFY_SOCKET") if unset_env
|
138
138
|
|
139
139
|
begin
|
140
|
-
Addrinfo.unix(sock, :DGRAM).connect
|
141
|
-
s.close_on_exec = true
|
142
|
-
s.write(state)
|
143
|
-
end
|
140
|
+
Addrinfo.unix(sock, :DGRAM).connect { |s| s.write state }
|
144
141
|
rescue StandardError => e
|
145
142
|
raise NotifyError, "#{e.class}: #{e.message}", e.backtrace
|
146
143
|
end
|
data/lib/puma/server.rb
CHANGED
@@ -233,6 +233,11 @@ module Puma
|
|
233
233
|
@thread_pool&.pool_capacity
|
234
234
|
end
|
235
235
|
|
236
|
+
# @!attribute [r] busy_threads
|
237
|
+
def busy_threads
|
238
|
+
@thread_pool&.busy_threads
|
239
|
+
end
|
240
|
+
|
236
241
|
# Runs the server.
|
237
242
|
#
|
238
243
|
# If +background+ is true (the default) then a thread is spun
|
@@ -253,9 +258,8 @@ module Puma
|
|
253
258
|
@reactor.run
|
254
259
|
end
|
255
260
|
|
256
|
-
|
257
261
|
@thread_pool.auto_reap! if options[:reaping_time]
|
258
|
-
@thread_pool.auto_trim! if options[:auto_trim_time]
|
262
|
+
@thread_pool.auto_trim! if @min_threads != @max_threads && options[:auto_trim_time]
|
259
263
|
|
260
264
|
@check, @notify = Puma::Util.pipe unless @notify
|
261
265
|
|
@@ -340,7 +344,7 @@ module Puma
|
|
340
344
|
@idle_timeout_reached = true
|
341
345
|
|
342
346
|
if @clustered
|
343
|
-
@worker_write << "#{PipeRequest::
|
347
|
+
@worker_write << "#{PipeRequest::PIPE_IDLE}#{Process.pid}\n" rescue nil
|
344
348
|
next
|
345
349
|
else
|
346
350
|
@log_writer.log "- Idle timeout reached"
|
@@ -353,7 +357,7 @@ module Puma
|
|
353
357
|
|
354
358
|
if @idle_timeout_reached && @clustered
|
355
359
|
@idle_timeout_reached = false
|
356
|
-
@worker_write << "#{PipeRequest::
|
360
|
+
@worker_write << "#{PipeRequest::PIPE_IDLE}#{Process.pid}\n" rescue nil
|
357
361
|
end
|
358
362
|
|
359
363
|
ios.first.each do |sock|
|
@@ -646,7 +650,7 @@ module Puma
|
|
646
650
|
|
647
651
|
# List of methods invoked by #stats.
|
648
652
|
# @version 5.0.0
|
649
|
-
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
|
650
654
|
|
651
655
|
# Returns a hash of stats about the running server for reporting purposes.
|
652
656
|
# @version 5.0.0
|
data/lib/puma/thread_pool.rb
CHANGED
@@ -91,7 +91,8 @@ module Puma
|
|
91
91
|
with_mutex do
|
92
92
|
{ backlog: @todo.size,
|
93
93
|
running: @spawned,
|
94
|
-
pool_capacity: @waiting + (@max - @spawned)
|
94
|
+
pool_capacity: @waiting + (@max - @spawned),
|
95
|
+
busy_threads: @spawned - @waiting + @todo.size
|
95
96
|
}
|
96
97
|
end
|
97
98
|
end
|
@@ -369,12 +370,12 @@ module Puma
|
|
369
370
|
end
|
370
371
|
|
371
372
|
def auto_trim!(timeout=@auto_trim_time)
|
372
|
-
@auto_trim = Automaton.new(self, timeout, "#{@name}
|
373
|
+
@auto_trim = Automaton.new(self, timeout, "#{@name} tp trim", :trim)
|
373
374
|
@auto_trim.start!
|
374
375
|
end
|
375
376
|
|
376
377
|
def auto_reap!(timeout=@reaping_time)
|
377
|
-
@reaper = Automaton.new(self, timeout, "#{@name}
|
378
|
+
@reaper = Automaton.new(self, timeout, "#{@name} tp reap", :reap)
|
378
379
|
@reaper.start!
|
379
380
|
end
|
380
381
|
|
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: 6.
|
4
|
+
version: 6.6.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|