puma 8.0.3-java → 8.1.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 +115 -0
- data/README.md +20 -5
- data/docs/6.0-Upgrade.md +1 -1
- data/docs/8.0-Upgrade.md +2 -2
- data/docs/deployment.md +3 -3
- data/docs/fork_worker.md +34 -4
- data/docs/kubernetes.md +3 -3
- data/docs/plugins.md +2 -2
- data/docs/puma_support.md +78 -0
- data/docs/rails_dev_mode.md +2 -2
- data/docs/restart.md +4 -3
- data/docs/signals.md +2 -2
- data/docs/stats.md +5 -5
- data/docs/systemd.md +4 -2
- data/docs/testing_benchmarks_local_files.md +1 -1
- data/docs/testing_test_rackup_ci_files.md +2 -2
- data/ext/puma_http11/extconf.rb +2 -0
- data/ext/puma_http11/http11_parser.c +6 -2
- data/ext/puma_http11/http11_parser_common.rl +4 -1
- data/ext/puma_http11/mini_ssl.c +8 -4
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +36 -36
- data/ext/puma_http11/puma_http11.c +24 -0
- data/lib/puma/binder.rb +29 -0
- data/lib/puma/cli.rb +6 -0
- data/lib/puma/client.rb +75 -29
- data/lib/puma/client_env.rb +32 -18
- data/lib/puma/cluster/worker.rb +109 -33
- data/lib/puma/cluster/worker_handle.rb +16 -0
- data/lib/puma/cluster.rb +173 -44
- data/lib/puma/commonlogger.rb +3 -3
- data/lib/puma/configuration.rb +22 -3
- data/lib/puma/const.rb +11 -9
- data/lib/puma/dsl.rb +265 -91
- data/lib/puma/launcher.rb +6 -4
- data/lib/puma/minissl.rb +1 -1
- data/lib/puma/plugin/systemd.rb +1 -1
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/response.rb +13 -5
- data/lib/puma/runner.rb +5 -1
- data/lib/puma/sd_notify.rb +4 -1
- data/lib/puma/server.rb +45 -20
- data/lib/puma/thread_pool.rb +12 -1
- data/lib/puma.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3e02c432552f5eaaac8c58b225f9f0dd3c22989934edd82cd1fb1bd29b5ba363
|
|
4
|
+
data.tar.gz: 64bc20c3349c3de9518aa40131410effa3d4bf7f7c6e5e761be5a1e9b13e0af9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1ac59882efd8822b4f068fd0705cd30ca35cfff1a3d1a653c6c208793f60642ec5d0206ca002cb21253ebffc0fca01cda74dbc42be0c996d27ec131ab41fdb27
|
|
7
|
+
data.tar.gz: e52b5670782329d492c1a3c8a2811ef183f7c4f46bb66fb8e2b109cf190a23202efd246e9a4eafdc8a886aeca4587d6c02cfbc6c95bae1edfc3e00ec94bb0521
|
data/History.md
CHANGED
|
@@ -1,3 +1,51 @@
|
|
|
1
|
+
## 8.1.0 / 2026-11-15
|
|
2
|
+
|
|
3
|
+
* Features
|
|
4
|
+
* Add experimental `mold_worker` cluster mode, an alternative to `fork_worker` where new workers are forked from a retired worker that no longer serves traffic ([#4038], [#4044], [#4055])
|
|
5
|
+
* Add `on_worker_boot` hooks and `hook_error_handler` ([#3982])
|
|
6
|
+
* Add `Puma::Client.connection_closed?` API ([#4019])
|
|
7
|
+
* Add `continue_callback` to answer `Expect: 100-continue` before the request body is read ([#4028])
|
|
8
|
+
* Send a systemd watchdog ping immediately on ready ([#3980])
|
|
9
|
+
* Support the HTTP `QUERY` method ([#3973])
|
|
10
|
+
* Allow a sub-second `worker_check_interval` ([#3964])
|
|
11
|
+
* Add `allow_underscore_headers` option; set it to `false` to discard request headers with underscores in their names ([#3937])
|
|
12
|
+
|
|
13
|
+
* Security (Hardening)
|
|
14
|
+
* Limit the size of a chunked request trailer section ([#4059])
|
|
15
|
+
* Reject unescaped `{`, `}`, `` ` `` and `\` in the request path ([#3976])
|
|
16
|
+
* Reject `Content_Length` and `Transfer_Encoding` framing headers regardless of `allow_underscore_headers` ([#4021])
|
|
17
|
+
* Clear the SSL key password callback after loading the private key ([#4027])
|
|
18
|
+
* Respond with 400 to HTTP/1.1 requests with a missing or empty `Host` header ([#3957])
|
|
19
|
+
* Reject empty chunk sizes ([#3952])
|
|
20
|
+
|
|
21
|
+
* Bugfixes
|
|
22
|
+
* Fix `IO#close` hang when `notify_safely` runs in a signal handler ([#4098])
|
|
23
|
+
* Fix `fork_worker` refork recovery ([#4056])
|
|
24
|
+
* Keep a socket-activated control URL for the control server ([#4037])
|
|
25
|
+
* Close path-backed response files when writing fails ([#4033])
|
|
26
|
+
* Don't send `content-length: 0` on 304 responses with an empty body ([#4036])
|
|
27
|
+
* Fix accepting one more request after the worker shutdown command is sent ([#4032])
|
|
28
|
+
* Honour the `close` option when it appears in a `Connection` header list ([#4031])
|
|
29
|
+
* Fix wakeup deadlock ([#4025])
|
|
30
|
+
* Fix `NoMethodError` when a malformed request has no request line ([#3992])
|
|
31
|
+
* Require `null_io` in `client.rb` so `puma/client` loads on its own ([#4024])
|
|
32
|
+
* Avoid keep-alive requeue into a shutting-down thread pool ([#4016])
|
|
33
|
+
* Fix `CommonLogger` nil-logger fallback to `rack.errors` ([#4023])
|
|
34
|
+
* Fix chunked body parsing when the last-chunk terminator arrives split ([#3970])
|
|
35
|
+
* Run `after_stopped` hooks after request draining ([#4001])
|
|
36
|
+
* Restore admission gate when `queue_requests` is disabled ([#3969])
|
|
37
|
+
* Fix `pool_capacity` leak when extra IO threads exit ([#3968])
|
|
38
|
+
* Fix worker shutdown hang in `notify_safely` ([#3940])
|
|
39
|
+
* Defer removal of `on_booted`, `on_restart` and `on_stopped` to Puma 9 ([#3938])
|
|
40
|
+
* Fix `Configuration#clamp` being called twice in `Launcher` ([#3939])
|
|
41
|
+
|
|
42
|
+
* Docs
|
|
43
|
+
* Add an initial Puma support document ([#3700])
|
|
44
|
+
* Document the bundled `sd_notify` license in the README ([#4102])
|
|
45
|
+
* Add a threat model to `SECURITY.md` ([#4064])
|
|
46
|
+
* Fix typos and grammar in README, CONTRIBUTING and docs ([#4035], [#3974])
|
|
47
|
+
* Improve DSL documentation, including `queue_requests` ([#3966], [#3965])
|
|
48
|
+
|
|
1
49
|
## 8.0.3 / 2026-11-13
|
|
2
50
|
|
|
3
51
|
* Security
|
|
@@ -63,6 +111,30 @@
|
|
|
63
111
|
* Breaking changes
|
|
64
112
|
* Default production bind address changed from `0.0.0.0` to `::` (IPv6) when a non-loopback IPv6 interface is available; falls back to `0.0.0.0` if IPv6 is unavailable ([#3847])
|
|
65
113
|
|
|
114
|
+
## 7.2.2 / 2026-11-13
|
|
115
|
+
|
|
116
|
+
* Security
|
|
117
|
+
* Close connections whose reactor timeout passed even when another client keeps sending data. ([GHSA-m5xw-3hrw-qcmf](https://github.com/puma/puma/security/advisories/GHSA-m5xw-3hrw-qcmf))
|
|
118
|
+
* Don't block the reactor writing a `100 Continue` or `408` to a client that stops reading. ([GHSA-xw3h-pgr9-3vg7](https://github.com/puma/puma/security/advisories/GHSA-xw3h-pgr9-3vg7))
|
|
119
|
+
* Apply the write timeout to TLS responses and to file responses larger than 64 KB, and don't let a TLS client that stops reading keep its connection alive by sending TLS records with no request data. ([GHSA-x646-wp7c-h9mg](https://github.com/puma/puma/security/advisories/GHSA-x646-wp7c-h9mg))
|
|
120
|
+
* Bound how long a graceful shutdown or restart keeps reading an incomplete request, with the new `shutdown_body_timeout` option (default 25 seconds). ([GHSA-jm4r-w4xx-qxw7](https://github.com/puma/puma/security/advisories/GHSA-jm4r-w4xx-qxw7))
|
|
121
|
+
* Keep `+` literal in bind URL query values, and raise on an invalid `ssl_cipher_filter`. ([GHSA-r885-m39c-939g](https://github.com/puma/puma/security/advisories/GHSA-r885-m39c-939g))
|
|
122
|
+
* Verify the TLS certificate and hostname of `ssl://` control servers in `pumactl`, with the new `--control-ca-file` option for private CAs. ([GHSA-86xc-wrr9-xmmq](https://github.com/puma/puma/security/advisories/GHSA-86xc-wrr9-xmmq))
|
|
123
|
+
* Back off and rate-limit logging when `accept` runs out of file descriptors. ([GHSA-rf6g-xhmp-gm7v](https://github.com/puma/puma/security/advisories/GHSA-rf6g-xhmp-gm7v))
|
|
124
|
+
|
|
125
|
+
CVE IDs have been requested for these advisories and will be added here once assigned.
|
|
126
|
+
|
|
127
|
+
* Bugfixes
|
|
128
|
+
* Send the idle notification from a clustered worker only once per idle period, so the master no longer stops an active cluster or delays an idle shutdown ([#4101])
|
|
129
|
+
* Fix build errors on Windows arm64 with Ruby head ([#4071])
|
|
130
|
+
* Send TLS `close_notify` when closing an SSL connection on JRuby ([#4029])
|
|
131
|
+
|
|
132
|
+
## 7.2.1 / 2026-05-27
|
|
133
|
+
|
|
134
|
+
* Bugfixes
|
|
135
|
+
* Limit and anchor PROXY protocol v1 parsing to prevent abuse via crafted inputs ([#3947])
|
|
136
|
+
* Parse PROXY protocol only once per connection to prevent injection on keep-alive requests ([#3947])
|
|
137
|
+
|
|
66
138
|
## 7.2.0 / 2026-01-20
|
|
67
139
|
|
|
68
140
|
* Features
|
|
@@ -2359,9 +2431,52 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
|
2359
2431
|
* Bugfixes
|
|
2360
2432
|
* Your bugfix goes here <Most recent on the top, like GitHub> (#Github Number)
|
|
2361
2433
|
|
|
2434
|
+
[#4059]:https://github.com/puma/puma/pull/4059 "PR by William T. Nelson, merged 2026-11-09"
|
|
2435
|
+
[#3976]:https://github.com/puma/puma/pull/3976 "PR by Maksim Romanov, merged 2026-10-02"
|
|
2436
|
+
[#4021]:https://github.com/puma/puma/pull/4021 "PR by Ted Ford, merged 2026-09-27"
|
|
2437
|
+
[#4027]:https://github.com/puma/puma/pull/4027 "PR by Joshua Young, merged 2026-09-27"
|
|
2438
|
+
[#3957]:https://github.com/puma/puma/pull/3957 "PR by Joel Stimson, merged 2026-07-08"
|
|
2439
|
+
[#3952]:https://github.com/puma/puma/pull/3952 "PR by Ben Kallus, merged 2026-06-22"
|
|
2440
|
+
[#4038]:https://github.com/puma/puma/pull/4038 "PR by Joshua Young, merged 2026-10-16"
|
|
2441
|
+
[#4044]:https://github.com/puma/puma/pull/4044 "PR by Joshua Young, merged 2026-10-24"
|
|
2442
|
+
[#4055]:https://github.com/puma/puma/pull/4055 "PR by Joshua Young, merged 2026-10-25"
|
|
2443
|
+
[#3982]:https://github.com/puma/puma/pull/3982 "PR by Giles, merged 2026-10-16"
|
|
2444
|
+
[#4019]:https://github.com/puma/puma/pull/4019 "PR by Henry Blyth, merged 2026-10-03"
|
|
2445
|
+
[#4028]:https://github.com/puma/puma/pull/4028 "PR by Islam Elsayed, merged 2026-10-03"
|
|
2446
|
+
[#3980]:https://github.com/puma/puma/pull/3980 "PR by Giles, merged 2026-09-27"
|
|
2447
|
+
[#3973]:https://github.com/puma/puma/pull/3973 "PR by Sean Doyle, merged 2026-07-11"
|
|
2448
|
+
[#3964]:https://github.com/puma/puma/pull/3964 "PR by Joshua Young, merged 2026-07-04"
|
|
2449
|
+
[#3937]:https://github.com/puma/puma/pull/3937 "PR by Nate Berkopec, merged 2026-05-27"
|
|
2450
|
+
[#4098]:https://github.com/puma/puma/pull/4098 "PR by Nate Berkopec, merged 2026-11-12"
|
|
2451
|
+
[#4056]:https://github.com/puma/puma/pull/4056 "PR by Joshua Young, merged 2026-10-25"
|
|
2452
|
+
[#4037]:https://github.com/puma/puma/pull/4037 "PR by Shai, merged 2026-10-16"
|
|
2453
|
+
[#4033]:https://github.com/puma/puma/pull/4033 "PR by Oskar Eichler, merged 2026-10-16"
|
|
2454
|
+
[#4036]:https://github.com/puma/puma/pull/4036 "PR by Bruno Tostes, merged 2026-10-16"
|
|
2455
|
+
[#4032]:https://github.com/puma/puma/pull/4032 "PR by kira tully, merged 2026-10-03"
|
|
2456
|
+
[#4031]:https://github.com/puma/puma/pull/4031 "PR by Januth Nimnal, merged 2026-10-03"
|
|
2457
|
+
[#4025]:https://github.com/puma/puma/pull/4025 "PR by Xavier, merged 2026-09-28"
|
|
2458
|
+
[#3992]:https://github.com/puma/puma/pull/3992 "PR by JinHyuk Sung, merged 2026-09-28"
|
|
2459
|
+
[#4024]:https://github.com/puma/puma/pull/4024 "PR by Shane Becker, merged 2026-09-27"
|
|
2460
|
+
[#4016]:https://github.com/puma/puma/pull/4016 "PR by Morax, merged 2026-09-27"
|
|
2461
|
+
[#4023]:https://github.com/puma/puma/pull/4023 "PR by Ethan Stoner, merged 2026-09-27"
|
|
2462
|
+
[#3970]:https://github.com/puma/puma/pull/3970 "PR by Joshua Young, merged 2026-09-03"
|
|
2463
|
+
[#4001]:https://github.com/puma/puma/pull/4001 "PR by Patrik Ragnarsson, merged 2026-08-31"
|
|
2464
|
+
[#3969]:https://github.com/puma/puma/pull/3969 "PR by Joshua Young, merged 2026-07-07"
|
|
2465
|
+
[#3968]:https://github.com/puma/puma/pull/3968 "PR by Joshua Young, merged 2026-07-04"
|
|
2466
|
+
[#3940]:https://github.com/puma/puma/pull/3940 "PR by Jesper Kjeldgaard, merged 2026-06-06"
|
|
2467
|
+
[#3938]:https://github.com/puma/puma/pull/3938 "PR by Patrik Ragnarsson, merged 2026-05-27"
|
|
2468
|
+
[#3939]:https://github.com/puma/puma/pull/3939 "PR by Joshua Young, merged 2026-05-25"
|
|
2469
|
+
[#3700]:https://github.com/puma/puma/pull/3700 "PR by Richard Schneeman, merged 2026-11-13"
|
|
2470
|
+
[#4102]:https://github.com/puma/puma/pull/4102 "PR by Nate Berkopec, merged 2026-11-13"
|
|
2471
|
+
[#4064]:https://github.com/puma/puma/pull/4064 "PR by Nate Berkopec, merged 2026-10-31"
|
|
2472
|
+
[#4035]:https://github.com/puma/puma/pull/4035 "PR by Bastin, merged 2026-10-08"
|
|
2473
|
+
[#3974]:https://github.com/puma/puma/pull/3974 "PR by max, merged 2026-07-30"
|
|
2474
|
+
[#3966]:https://github.com/puma/puma/pull/3966 "PR by Joshua Young, merged 2026-07-04"
|
|
2475
|
+
[#3965]:https://github.com/puma/puma/pull/3965 "PR by Joshua Young, merged 2026-07-04"
|
|
2362
2476
|
[#4101]:https://github.com/puma/puma/pull/4101 "PR by Nate Berkopec, merged 2026-11-13"
|
|
2363
2477
|
[#4071]:https://github.com/puma/puma/pull/4071 "PR by Nate Berkopec, merged 2026-11-09"
|
|
2364
2478
|
[#4029]:https://github.com/puma/puma/pull/4029 "PR by Islam Elsayed, merged 2026-09-28"
|
|
2479
|
+
[#3947]:https://github.com/puma/puma/pull/3947 "PR by Nate Berkopec, merged 2026-05-26"
|
|
2365
2480
|
[#3944]:https://github.com/puma/puma/pull/3944 "PR by Nate Berkopec, merged 2026-05-26"
|
|
2366
2481
|
[#3929]:https://github.com/puma/puma/pull/3929 "PR by Joshua Young, merged 2026-04-26"
|
|
2367
2482
|
[#3928]:https://github.com/puma/puma/pull/3928 "PR by Nate Berkopec, merged 2026-04-16"
|
data/README.md
CHANGED
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
[](https://github.com/puma/puma/actions/workflows/tests.yml?query=branch%3Amain)
|
|
8
8
|
|
|
9
|
+
<a href="https://commitgoods.com/collections/puma?utm_source=github&utm_medium=referral">
|
|
10
|
+
<picture>
|
|
11
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.shopify.com/s/files/1/0101/8752/files/commitgoods-badge-stacked-navy-dark.svg">
|
|
12
|
+
<img src="https://cdn.shopify.com/s/files/1/0101/8752/files/commitgoods-badge-stacked-navy.svg" height="28" alt="Official merch on commitgoods.com">
|
|
13
|
+
</picture>
|
|
14
|
+
</a>
|
|
15
|
+
|
|
9
16
|
Puma is a **simple, fast, multi-threaded, and highly parallel HTTP 1.1 server for Ruby/Rack applications**.
|
|
10
17
|
|
|
11
18
|
## Built For Speed & Parallelism
|
|
@@ -28,7 +35,7 @@ $ puma
|
|
|
28
35
|
```
|
|
29
36
|
|
|
30
37
|
Without arguments, puma will look for a rackup (.ru) file in
|
|
31
|
-
working directory called `config.ru`.
|
|
38
|
+
the working directory called `config.ru`.
|
|
32
39
|
|
|
33
40
|
## SSL Connection Support
|
|
34
41
|
|
|
@@ -171,7 +178,7 @@ after_worker_shutdown do |worker_handle|
|
|
|
171
178
|
end
|
|
172
179
|
```
|
|
173
180
|
|
|
174
|
-
In addition, there
|
|
181
|
+
In addition, there are `before_refork` and `after_refork` hooks which are used only in [`fork_worker` mode](docs/fork_worker.md),
|
|
175
182
|
when the worker 0 child process forks a grandchild worker:
|
|
176
183
|
|
|
177
184
|
```ruby
|
|
@@ -225,8 +232,8 @@ before_restart do
|
|
|
225
232
|
end
|
|
226
233
|
|
|
227
234
|
after_stopped do
|
|
228
|
-
# Add code to run in the Puma master process
|
|
229
|
-
#
|
|
235
|
+
# Add code to run in the Puma master process after outstanding
|
|
236
|
+
# requests have finished and Puma has stopped.
|
|
230
237
|
end
|
|
231
238
|
```
|
|
232
239
|
|
|
@@ -258,6 +265,8 @@ Bind Puma to a socket with the `-b` (or `--bind`) flag:
|
|
|
258
265
|
$ puma -b tcp://127.0.0.1:9292
|
|
259
266
|
```
|
|
260
267
|
|
|
268
|
+
When using a TCP socket on Linux, Puma will automatically skip requests whose connection has closed by the time it's taken from the queue. If you'd like to avoid wasting time on connections that are closing after your app starts handling them, you can call `env["puma.connection_closed?"]` at any time during the lifecycle of a request. A `false` result does not guarantee that the connection will remain open. Puma cannot check this for you during a request: it is waiting for your app to return a response.
|
|
269
|
+
|
|
261
270
|
To use a UNIX Socket instead of TCP:
|
|
262
271
|
|
|
263
272
|
```
|
|
@@ -392,7 +401,7 @@ Puma has a built-in status and control app that can be used to query and control
|
|
|
392
401
|
$ puma --control-url tcp://127.0.0.1:9293 --control-token foo
|
|
393
402
|
```
|
|
394
403
|
|
|
395
|
-
Puma will start the control server on localhost port 9293. All requests to the control server will need to include control token (in this case, `token=foo`) as a query parameter. This allows for simple authentication. Check out `Puma::App::Status` or [status.rb](https://github.com/puma/puma/blob/main/lib/puma/app/status.rb) to see what the status app has available.
|
|
404
|
+
Puma will start the control server on localhost port 9293. All requests to the control server will need to include a control token (in this case, `token=foo`) as a query parameter. This allows for simple authentication. Check out `Puma::App::Status` or [status.rb](https://github.com/puma/puma/blob/main/lib/puma/app/status.rb) to see what the status app has available.
|
|
396
405
|
|
|
397
406
|
You can also interact with the control server via `pumactl`. This command will restart Puma:
|
|
398
407
|
|
|
@@ -475,6 +484,10 @@ Community guides:
|
|
|
475
484
|
|
|
476
485
|
* [puma-status](https://github.com/ylecuyer/puma-status) — Monitor CPU/Mem/Load of running puma instances from the CLI
|
|
477
486
|
|
|
487
|
+
## Merchandise
|
|
488
|
+
|
|
489
|
+
Puma stickers, shirts, hoodies, and mugs are available at [commitgoods.com](https://commitgoods.com/collections/puma?utm_source=github&utm_medium=referral).
|
|
490
|
+
|
|
478
491
|
## Contributing
|
|
479
492
|
|
|
480
493
|
Find details for contributing in the [contribution guide](CONTRIBUTING.md).
|
|
@@ -482,3 +495,5 @@ Find details for contributing in the [contribution guide](CONTRIBUTING.md).
|
|
|
482
495
|
## License
|
|
483
496
|
|
|
484
497
|
Puma is copyright Evan Phoenix and contributors, licensed under the BSD 3-Clause license. See the included LICENSE file for details.
|
|
498
|
+
|
|
499
|
+
Puma includes a copy of [`sd_notify`](https://github.com/agis/ruby-sdnotify) (commit `cca575c`), licensed under the MIT license. See [`lib/puma/sd_notify.rb`](lib/puma/sd_notify.rb) for the license text.
|
data/docs/6.0-Upgrade.md
CHANGED
|
@@ -27,7 +27,7 @@ We've improved throughput and latency in Puma 6 in a few areas.
|
|
|
27
27
|
|
|
28
28
|
### Experimental Rack 3 Support
|
|
29
29
|
|
|
30
|
-
[Rack 3 is now out](https://github.com/rack/rack/blob/main/UPGRADE-GUIDE.md) and we've started on Rack 3 support. Please open a bug if you find any
|
|
30
|
+
[Rack 3 is now out](https://github.com/rack/rack/blob/main/UPGRADE-GUIDE.md) and we've started on Rack 3 support. Please open a bug if you find any incompatibilities.
|
|
31
31
|
|
|
32
32
|
### Sidekiq 7 Capsules
|
|
33
33
|
|
data/docs/8.0-Upgrade.md
CHANGED
|
@@ -33,7 +33,7 @@ run lambda { |env|
|
|
|
33
33
|
}
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
We anticipate this will mainly
|
|
36
|
+
We anticipate this will mainly be used by framework authors who have threads or types of requests they know are extremely IO-bound, and don't recommend it for use at the application level.
|
|
37
37
|
|
|
38
38
|
**Thread pool limits can be changed at runtime.** Puma now exposes `Puma::Server#update_thread_pool_min_max`, and hook/plugin code can do the same through `Puma::ServerPluginControl`.
|
|
39
39
|
|
|
@@ -91,7 +91,7 @@ bind 'tcp://0.0.0.0:9292'
|
|
|
91
91
|
|
|
92
92
|
Check the following list to see if you're depending on any of these behaviors:
|
|
93
93
|
|
|
94
|
-
1. Puma will now listen on `::` (IPv6) by default. Previously, it listened to `0.0.0.0` (IPv4). Systems that support both IPv6 and IPv4 (Ubuntu and Mac commonly do) will still support receiving to `0.0.0.0`. See [
|
|
94
|
+
1. Puma will now listen on `::` (IPv6) by default. Previously, it listened to `0.0.0.0` (IPv4). Systems that support both IPv6 and IPv4 (Ubuntu and Mac commonly do) will still support receiving to `0.0.0.0`. See [the support table in the PR](https://github.com/puma/puma/pull/3847) for binding compatibility. For systems that ONLY bind to IPv6 (without IPv4 support) this may be a breaking change. You can overwrite this default behavior by setting `bind 'tcp://0.0.0.0:9292'`, `port ENV.fetch('PORT', 9292), '0.0.0.0'`, or `set_default_host '0.0.0.0'` explicitly to remain IPv4 only. Review any firewall rules, health checks, deploy scripts, or host-string parsing code that assumed `0.0.0.0`, `127.0.0.1`, or unbracketed `HOST:PORT` formatting.
|
|
95
95
|
2. If you explicitly configure `bind 'tcp://[::]:...'`, `bind 'ssl://[::]:...'`, or equivalent `ssl_bind '::', ...`, Puma will now rewrite that unspecified IPv6 bind to `0.0.0.0` when the host has no non-loopback IPv6 interface, and it will warn on boot. If you were using `::` to force IPv6-only behavior or to detect IPv6 availability, switch to a concrete IPv6 address instead of `::`, or ensure the machine actually has a usable IPv6 interface before Puma starts.
|
|
96
96
|
3. `before_thread_start` hooks now receive a `Puma::ServerPluginControl` argument. Update any zero-arity lambdas, method objects, or other strict-arity hook code to accept one argument, for example `before_thread_start { |_control| ... }`, or Puma can raise `ArgumentError` when the hook runs.
|
|
97
97
|
4. On platforms without `SIGINFO`, Puma now traps `SIGPWR`, and `pumactl info` sends `SIGPWR` there. If your supervisor, init script, or container tooling already uses `SIGPWR` for something else, change that wiring before upgrading and update any runbooks that assumed Puma would ignore `SIGPWR`.
|
data/docs/deployment.md
CHANGED
|
@@ -66,7 +66,7 @@ If latency is important to you, you will have to accept lower utilization, and v
|
|
|
66
66
|
|
|
67
67
|
You will have to make a decision about how "big" to make each pod/VPS/server/dyno.
|
|
68
68
|
|
|
69
|
-
**TL
|
|
69
|
+
**TL;DR**: 80% of Puma apps will end up deploying "pods" of 4 workers, 5 threads each, 4 vCPU and 8GB of RAM.
|
|
70
70
|
|
|
71
71
|
For the rest of this discussion, we'll adopt the Kubernetes term of "pods".
|
|
72
72
|
|
|
@@ -109,11 +109,11 @@ to monitor them as child processes. This gives them fast response to crashes and
|
|
|
109
109
|
makes it easy to figure out what is going on. Additionally, unlike `unicorn`,
|
|
110
110
|
Puma does not require daemonization to do zero-downtime restarts.
|
|
111
111
|
|
|
112
|
-
I see people using daemonization because they start puma directly via Capistrano
|
|
112
|
+
I see people using daemonization because they start puma directly via a Capistrano
|
|
113
113
|
task and thus want it to live on past the `cap deploy`. To these people, I say:
|
|
114
114
|
You need to be using a process monitor. Nothing is making sure Puma stays up in
|
|
115
115
|
this scenario! You're just waiting for something weird to happen, Puma to die,
|
|
116
|
-
and to get paged at 3 AM. Do yourself a favor, at least the process monitoring
|
|
116
|
+
and to get paged at 3 AM. Do yourself a favor, at least use the process monitoring
|
|
117
117
|
your OS comes with, be it `sysvinit` or `systemd`. Or branch out and use `runit`
|
|
118
118
|
or hell, even `monit`.
|
|
119
119
|
|
data/docs/fork_worker.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Fork-Worker Cluster Mode [Experimental]
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`fork_worker` (`--fork-worker` from the CLI) is an experimental cluster-mode configuration option. This mode causes Puma to fork additional workers from worker 0, instead of directly from the master process.
|
|
4
4
|
|
|
5
5
|
```
|
|
6
|
-
10000 \_ puma
|
|
6
|
+
10000 \_ puma 8.0.2 (tcp://0.0.0.0:9292) [puma]
|
|
7
7
|
10001 \_ puma: cluster worker 0: 10000 [puma]
|
|
8
8
|
10002 \_ puma: cluster worker 1: 10000 [puma]
|
|
9
9
|
10003 \_ puma: cluster worker 2: 10000 [puma]
|
|
@@ -12,7 +12,7 @@ Puma 5 introduces an experimental new cluster-mode configuration option, `fork_w
|
|
|
12
12
|
|
|
13
13
|
The `fork_worker` option allows your application to be initialized only once for copy-on-write memory savings, and it has two additional advantages:
|
|
14
14
|
|
|
15
|
-
1. **Compatible with phased restart.**
|
|
15
|
+
1. **Compatible with phased restart.** With `preload_app!` disabled, the master process doesn't load the application, so this mode works with phased restart (`SIGUSR1` or `pumactl phased-restart`). When worker 0 reloads as part of a phased restart, it initializes a new copy of your application first, then the other workers reload by forking from this new worker already containing the new preloaded application.
|
|
16
16
|
|
|
17
17
|
This allows a phased restart to complete as quickly as a hot restart (`SIGUSR2` or `pumactl restart`), while still minimizing downtime by staggering the restart across cluster workers.
|
|
18
18
|
|
|
@@ -30,7 +30,7 @@ The `fork_worker` option allows your application to be initialized only once for
|
|
|
30
30
|
- For clarity, `before_fork` does not trigger on worker 0, and `after_refork` does not trigger on the grandchild.
|
|
31
31
|
- As a general migration guide:
|
|
32
32
|
- Copy any logic within your existing `before_fork` hook to the `before_refork` hook.
|
|
33
|
-
- Consider
|
|
33
|
+
- Consider copying logic from your `before_worker_boot` hook to the `after_refork` hook, if it is needed to reset the state of worker 0 after it forks.
|
|
34
34
|
|
|
35
35
|
### Limitations
|
|
36
36
|
|
|
@@ -39,3 +39,33 @@ The `fork_worker` option allows your application to be initialized only once for
|
|
|
39
39
|
- In order to fork new workers cleanly, worker 0 shuts down its server and stops serving requests so there are no open file descriptors or other kinds of shared global state between processes, and to maximize copy-on-write efficiency across the newly-forked workers. This may temporarily reduce total capacity of the cluster during a phased restart / refork.
|
|
40
40
|
|
|
41
41
|
- In a cluster with `n` workers, a normal phased restart stops and restarts workers one by one while the application is loaded in each process, so `n-1` workers are available serving requests during the restart. In a phased restart in fork-worker mode, the application is first loaded in worker 0 while `n-1` workers are available, then worker 0 remains stopped while the rest of the workers are reloaded one by one, leaving only `n-2` workers to be available for a brief period of time. Reloading the rest of the workers should be quick because the application is preloaded at that point, but there may be situations where it can take longer (slow clients, long-running application code, slow worker-fork hooks, etc).
|
|
42
|
+
|
|
43
|
+
# Mold-Worker Cluster Mode [Experimental]
|
|
44
|
+
|
|
45
|
+
`mold_worker` (`--mold-worker` from the CLI) is an alternative to `fork_worker`. Instead of forking from a worker that also serves requests, Puma promotes a worker to a "mold", which stops serving requests and only forks new workers. Because the mold never serves traffic, a slow request, timeout or memory limit can't take it down mid-refork.
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
10000 \_ puma 8.0.2 (tcp://0.0.0.0:9292) [puma]
|
|
49
|
+
10005 \_ puma: mold 2: 10000 [puma]
|
|
50
|
+
10011 \_ puma: cluster worker 0: 10000 [puma]
|
|
51
|
+
10012 \_ puma: cluster worker 1: 10000 [puma]
|
|
52
|
+
10013 \_ puma: cluster worker 2: 10000 [puma]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Workers are forked from the master at boot. Each request threshold (default `1000`) promotes the busiest worker to a new mold, retires the previous one, and reforks every worker from the new mold.
|
|
56
|
+
|
|
57
|
+
```ruby
|
|
58
|
+
mold_worker 1000, 2000, 4000
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Usage Considerations
|
|
62
|
+
|
|
63
|
+
- Thresholds are per worker, counted from when that worker booted. Workers forked from a mold start again at zero, so with the config above a worker is promoted after 1000 requests, and a worker from that generation is promoted after another 2000.
|
|
64
|
+
- After the last threshold, molds are only replaced by `SIGURG` or `pumactl refork`, which promote the busiest worker at any time.
|
|
65
|
+
- A phased restart (`SIGUSR1` or `pumactl phased-restart`) retires the mold and forks workers from the master, so new code is loaded, then starts the thresholds again. As with any phased restart, this requires `preload_app!` to be disabled.
|
|
66
|
+
- `mold_worker` cannot be combined with `fork_worker`.
|
|
67
|
+
- On Linux 3.4+, workers are reparented to the master rather than orphaned if their mold exits.
|
|
68
|
+
- `mold_worker` introduces new `after_mold_promotion` and `before_mold_shutdown` configuration hooks.
|
|
69
|
+
- `after_mold_promotion` runs in the mold after it stops serving requests, before it forks any workers. Use it for what you would do in `before_refork`, such as closing connections or running garbage collection.
|
|
70
|
+
- `before_mold_shutdown` runs in the mold before it exits.
|
|
71
|
+
- `before_worker_boot` runs in each forked worker, as usual. Use it for what you would do in `after_refork`.
|
data/docs/kubernetes.md
CHANGED
|
@@ -57,13 +57,13 @@ For some high-throughput systems, it is possible that some HTTP requests will re
|
|
|
57
57
|
|
|
58
58
|
1. The replication controller determines a pod should be shut down.
|
|
59
59
|
2. The Pod is set to the “Terminating” State and removed from the endpoints list of all Services, so that it receives no more requests.
|
|
60
|
-
3. The
|
|
60
|
+
3. The pod's pre-stop hook gets called. The default for this is to send `SIGTERM` to the process inside the pod.
|
|
61
61
|
4. The pod has up to `terminationGracePeriodSeconds` (default: 30 seconds) to gracefully shut down. Puma will do this (after it receives SIGTERM) by closing down the socket that accepts new requests and finishing any requests already running before exiting the Puma process.
|
|
62
62
|
5. If the pod is still running after `terminationGracePeriodSeconds` has elapsed, the pod receives `SIGKILL` to make sure the process inside it stops. After that, the container exits and all other Kubernetes objects associated with it are cleaned up.
|
|
63
63
|
|
|
64
|
-
There is a subtle race condition between
|
|
64
|
+
There is a subtle race condition between steps 2 and 3: The replication controller does not synchronously remove the pod from the Services AND THEN call the pre-stop hook of the pod, but rather it asynchronously sends "remove this pod from your endpoints" requests to the Services and then immediately proceeds to invoke the pod's pre-stop hook. If the Service controller (typically something like nginx or haproxy) receives and handles this request "too" late (due to internal lag or network latency between the replication and Service controllers) then it is possible that the Service controller will send one or more requests to a Puma process which has already shut down its listening socket. These requests will then fail with 5XX error codes.
|
|
65
65
|
|
|
66
|
-
The
|
|
66
|
+
The reason Kubernetes works this way, rather than handling step 2 synchronously, is due to the CAP theorem: in a distributed system there is no way to guarantee that any message will arrive promptly. In particular, waiting for all Service controllers to report back might get stuck for an indefinite time if one of them has already been terminated or if there has been a net split. A way to work around this is to add a sleep to the pre-stop hook of the same time as the `terminationGracePeriodSeconds` time. This will allow the Puma process to keep serving new requests during the entire grace period, although it will no longer receive new requests after all Service controllers have propagated the removal of the pod from their endpoint lists. Then, after `terminationGracePeriodSeconds`, the pod receives `SIGKILL` and closes down. If your process can't handle SIGKILL properly, for example because it needs to release locks in different services, you can also sleep for a shorter period (and/or increase `terminationGracePeriodSeconds`) as long as the time slept is longer than the time that your Service controllers take to propagate the pod removal. The downside of this workaround is that all pods will take at minimum the amount of time slept to shut down and this will increase the time required for your rolling deploy.
|
|
67
67
|
|
|
68
68
|
More discussions and links to relevant articles can be found in https://github.com/puma/puma/issues/2343.
|
|
69
69
|
|
data/docs/plugins.md
CHANGED
|
@@ -14,7 +14,7 @@ There are two canonical plugins to aid in the development of new plugins:
|
|
|
14
14
|
Plugins are activated in a Puma configuration file (such as `config/puma.rb`)
|
|
15
15
|
by adding `plugin "name"`, such as `plugin "heroku"`.
|
|
16
16
|
|
|
17
|
-
Plugins are activated based on path requirements so
|
|
17
|
+
Plugins are activated based on path requirements, so activating the `heroku`
|
|
18
18
|
plugin is much like `require "puma/plugin/heroku"`. This allows gems to provide
|
|
19
19
|
multiple plugins (as well as unrelated gems to provide Puma plugins).
|
|
20
20
|
|
|
@@ -39,4 +39,4 @@ public API for plugins.
|
|
|
39
39
|
|
|
40
40
|
## Binder hooks
|
|
41
41
|
|
|
42
|
-
There's `Puma::Binder#before_parse` method that allows
|
|
42
|
+
There's a `Puma::Binder#before_parse` method that allows adding a 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) unnecessary).
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Puma Support Policy
|
|
2
|
+
|
|
3
|
+
## What
|
|
4
|
+
|
|
5
|
+
This document's purpose is to help users and contributors of this library make future plans based on the trajectory of this project. It is loosely worded and should be expected to change over time. Maintainers and contributors are encouraged to follow the guidance here but are not strictly bound by it.
|
|
6
|
+
|
|
7
|
+
## What does "supported" mean?
|
|
8
|
+
|
|
9
|
+
Puma is a community-run project. "Support" means "what do the maintainers pay attention to and what are they likely to merge", and doesn't mean that we do anything by any particular date, or even at all. We may all jet off to a private island tomorrow and never speak again.
|
|
10
|
+
|
|
11
|
+
But, if we do decide to keep devoting our free time to open source software, we will **support the environments (combinations of Ruby version, Ruby implementation, Rack version, and operating system) which run on our CI.**
|
|
12
|
+
|
|
13
|
+
If you open a PR or bug report for a combination of those factors outside of our CI matrix, we may still accept it if it's a small and low-risk fix.
|
|
14
|
+
|
|
15
|
+
We may add environments to CI at any time, but we only drop a supported environment in a minor or major release.
|
|
16
|
+
|
|
17
|
+
## Puma release support policy
|
|
18
|
+
|
|
19
|
+
By default, Puma supports one release version, the latest release. That means if there is a bug in 3.2.1 (made-up numbers for example only), but the latest release is 4.3.2, the bug must be reproduced in 4.3.2 to qualify for support.
|
|
20
|
+
|
|
21
|
+
When a new major (and sometimes minor) version is released, Puma maintainers will try to preserve the status of the old version via branches and/or tags. Puma maintainers can choose to backport fixes to older versions and cut a release of older versions, but this behavior should not be assumed.
|
|
22
|
+
|
|
23
|
+
If a bug report cannot be reproduced with the latest Puma version, it may be closed.
|
|
24
|
+
|
|
25
|
+
## Ruby version support policy
|
|
26
|
+
|
|
27
|
+
"Ruby version" refers to the https://github.com/ruby/ruby implementation. Puma also supports other Ruby implementations (the origin of Puma involves an alternate Ruby implementation, Rubinius); see below.
|
|
28
|
+
|
|
29
|
+
Ruby upstream support is documented at https://www.ruby-lang.org/en/downloads/branches/. A "minor" version is X.Y, with X.Y.Z being a patch release. Puma supports every Ruby minor version that is not EOL upstream. Puma may also continue to support older, EOL Ruby versions; the gemspec's `required_ruby_version` declares the oldest supported version. Maintainers decide when to raise that minimum. The Puma team recommends you always use the latest Ruby release.
|
|
30
|
+
|
|
31
|
+
When Puma supports a Ruby version, it will include that version in the CI matrix. CI runs only the most recent patch version of each supported Ruby minor version. If a bug is reported, the report must be reproducible using the most recent patch version of a currently supported Ruby minor version.
|
|
32
|
+
|
|
33
|
+
Puma may rely on upstream support to fix bugs in Ruby rather than working around them. That means, if a bug exists only in a Ruby version that is EOL upstream, it may be closed (it's not guaranteed that we will work around legacy Ruby issues).
|
|
34
|
+
|
|
35
|
+
When Puma does work around a bug in a specific Ruby patch version, the workaround stays until Puma drops support for that Ruby minor version.
|
|
36
|
+
|
|
37
|
+
## Alternate implementations of Ruby (version support policy)
|
|
38
|
+
|
|
39
|
+
An example of an "alternate" implementation of Ruby is JRuby. Ruby implementations typically target a specific "spec" of ruby/ruby, for example, JRuby 10.0 targets ruby/ruby version 3.4. The target version of a supported implementation must be within the above "Ruby version support policy." Additionally, the implementation release must be supported upstream.
|
|
40
|
+
|
|
41
|
+
Puma supports the JRuby implementation. Puma supports the TruffleRuby implementation.
|
|
42
|
+
|
|
43
|
+
## Rack (and SPEC) version support
|
|
44
|
+
|
|
45
|
+
From the current Rack documentation https://github.com/rack/rack?tab=readme-ov-file#version-support, Rack lists support levels to be:
|
|
46
|
+
|
|
47
|
+
- Bug fixes and security patches
|
|
48
|
+
- Security patches only
|
|
49
|
+
- End of support
|
|
50
|
+
|
|
51
|
+
Puma will support any Rack version that still accepts "bug fixes" in addition to security patches. Rack versions that receive only security patches, or are at end of support, are not supported.
|
|
52
|
+
|
|
53
|
+
Due to the need to support "hot" reloading applications (via phased restart) which might have different Rack versions, [Puma cannot directly declare the minimum Rack version](https://github.com/puma/puma/commit/537bc21593182cd9c4c0079a3936d05b1f91fe14). Puma may use runtime or boot time checks to warn or error about Rack version support.
|
|
54
|
+
|
|
55
|
+
## Bundler version support
|
|
56
|
+
|
|
57
|
+
Puma supports the Bundler version that ships with each supported Ruby version.
|
|
58
|
+
|
|
59
|
+
## How to use this document
|
|
60
|
+
|
|
61
|
+
You can use the guidelines here to make suggestions to contributors (anyone reporting an issue, helping with via a comment, or opening a PR) or maintainers. For example, "I could not reproduce your issue using a currently supported Ruby version. Can you please update to version X.Y and verify the issue persists?" Please link to this doc, state what action you're requesting, and why you feel that action is supported by this document. Please act in "good faith" and do not "bikeshed" (the practice of focusing on non-structural or seemingly irrelevant details).
|
|
62
|
+
|
|
63
|
+
## How to update this document?
|
|
64
|
+
|
|
65
|
+
Generally, you shouldn't suggest changes to policies in this document unless you have committed to the Puma project.
|
|
66
|
+
|
|
67
|
+
Non-committers:
|
|
68
|
+
|
|
69
|
+
- Spelling fixes are fine; do not re-grammar or "refactor" the wording.
|
|
70
|
+
- Updating stale details derived from the policies is fine. For example, if a canonical URL changes or if specific upstream versions are listed.
|
|
71
|
+
|
|
72
|
+
Committers:
|
|
73
|
+
|
|
74
|
+
- Suggest whatever policy changes you feel are appropriate.
|
|
75
|
+
- Suggest improvements to the wording or consistency or presentation of information.
|
|
76
|
+
- Do not merge policy changes without oversight of other "significant" contributors.
|
|
77
|
+
- When reviewing a policy change, please mark comments as either blocking or non/blocking. Please try to make blocking comments either satisfiable or falsifiable.
|
|
78
|
+
|
data/docs/rails_dev_mode.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## "Loopback requests"
|
|
4
4
|
|
|
5
|
-
Be cautious of "loopback requests," where a Rails application executes a request to a server that, in turn, results in another request back to the same Rails application before the first request completes. Having a loopback request will trigger [Rails' load interlock](https://guides.rubyonrails.org/threading_and_code_execution.html#load-interlock) mechanism. The load interlock mechanism prevents a thread from using Rails autoloading mechanism to load constants while the application code is still running inside another thread.
|
|
5
|
+
Be cautious of "loopback requests," where a Rails application executes a request to a server that, in turn, results in another request back to the same Rails application before the first request completes. Having a loopback request will trigger [Rails' load interlock](https://guides.rubyonrails.org/threading_and_code_execution.html#load-interlock) mechanism. The load interlock mechanism prevents a thread from using Rails' autoloading mechanism to load constants while the application code is still running inside another thread.
|
|
6
6
|
|
|
7
7
|
This issue only occurs in the development environment as Rails' load interlock is not used in production environments. Although we're not sure, we believe this issue may not occur with the new `zeitwerk` code loader.
|
|
8
8
|
|
|
@@ -25,4 +25,4 @@ do_something_with response
|
|
|
25
25
|
|
|
26
26
|
#### 2. Use multiple processes on Puma
|
|
27
27
|
|
|
28
|
-
Alternatively, you may also enable multiple (single-threaded) workers on Puma. By doing so, you are sidestepping the problem by creating multiple processes rather than new threads. However, this workaround is not ideal because debugging tools such as [byebug](https://github.com/deivid-rodriguez/byebug/issues/487) and [pry](https://github.com/pry/pry/issues/2153)
|
|
28
|
+
Alternatively, you may also enable multiple (single-threaded) workers on Puma. By doing so, you are sidestepping the problem by creating multiple processes rather than new threads. However, this workaround is not ideal because debugging tools such as [byebug](https://github.com/deivid-rodriguez/byebug/issues/487) and [pry](https://github.com/pry/pry/issues/2153) work poorly with any multi-process web server.
|
data/docs/restart.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Puma provides three distinct kinds of restart operations, each for different use cases. This document describes "hot restarts" and "phased restarts." The third kind of restart operation is called "refork" and is described in the documentation for [`fork_worker`](fork_worker.md).
|
|
1
|
+
Puma provides three distinct kinds of restart operations, each for different use cases. This document describes "hot restarts" and "phased restarts." The third kind of restart operation is called "refork" and is described in the documentation for [`fork_worker` and `mold_worker`](fork_worker.md).
|
|
2
2
|
|
|
3
3
|
## Hot restart
|
|
4
4
|
|
|
@@ -27,8 +27,9 @@ Any of the following will cause a Puma server to perform a hot restart:
|
|
|
27
27
|
|
|
28
28
|
### Additional notes
|
|
29
29
|
|
|
30
|
-
* The newly started Puma process changes its current working directory to the directory specified by the `directory` option. If `directory` is set to symlink, this is automatically re-evaluated, so this mechanism can be used to upgrade the application.
|
|
30
|
+
* The newly started Puma process changes its current working directory to the directory specified by the `directory` option. If `directory` is set to a symlink, this is automatically re-evaluated, so this mechanism can be used to upgrade the application.
|
|
31
31
|
* Only one version of the application is running at a time.
|
|
32
|
+
* Under systemd with `WatchdogSec` set, the watchdog timer keeps running across a hot restart. Puma pings the watchdog as soon as the new master reports readiness, so `WatchdogSec` needs to exceed your application's boot time.
|
|
32
33
|
* `before_restart` is invoked just before the server shuts down. This can be used to clean up resources (like long-lived database connections) gracefully. Since Ruby 2.0, it is not typically necessary to explicitly close file descriptors on restart. This is because any file descriptor opened by Ruby will have the `FD_CLOEXEC` flag set, meaning that file descriptors are closed on `exec`. `before_restart` is useful, though, if your application needs to perform any more graceful protocol-specific shutdown procedures before closing connections.
|
|
33
34
|
|
|
34
35
|
## Phased restart
|
|
@@ -57,7 +58,7 @@ Any of the following will cause a Puma server to perform a phased restart:
|
|
|
57
58
|
|
|
58
59
|
### Additional notes
|
|
59
60
|
|
|
60
|
-
* When a phased restart begins, the Puma master process changes its current working directory to the directory specified by the `directory` option. If `directory` is set to symlink, this is automatically re-evaluated, so this mechanism can be used to upgrade the application.
|
|
61
|
+
* When a phased restart begins, the Puma master process changes its current working directory to the directory specified by the `directory` option. If `directory` is set to a symlink, this is automatically re-evaluated, so this mechanism can be used to upgrade the application.
|
|
61
62
|
* On a single server, it's possible that two versions of the application are running concurrently during a phased restart.
|
|
62
63
|
* `before_restart` is not invoked
|
|
63
64
|
* Phased restarts can be slow for Puma clusters with many workers. Hot restarts often complete more quickly, but at the cost of increased latency during the restart.
|
data/docs/signals.md
CHANGED
|
@@ -40,8 +40,8 @@ Puma cluster responds to these signals:
|
|
|
40
40
|
- `USR1`: Restart workers in phases, a rolling restart. This will not reload the configuration file.
|
|
41
41
|
- `HUP`: Reopen log files defined in `stdout_redirect` configuration parameter. If there is no `stdout_redirect` option provided, it will behave like `INT`.
|
|
42
42
|
- `INT`: Equivalent of sending Ctrl-C to cluster. Puma will attempt to finish then exit.
|
|
43
|
-
- `CHLD`: Reap zombie child processes and wake event loop in `fork_worker`
|
|
44
|
-
- `URG`: Refork workers in phases from worker 0 if `fork_worker` option is enabled.
|
|
43
|
+
- `CHLD`: Reap zombie child processes and wake event loop in `fork_worker` and `mold_worker` modes.
|
|
44
|
+
- `URG`: Refork workers in phases from worker 0 if `fork_worker` option is enabled, or from a newly promoted mold if `mold_worker` option is enabled.
|
|
45
45
|
- `INFO` (or `PWR` for systems without `INFO`) print backtraces of all puma threads (if supported on your platform).
|
|
46
46
|
|
|
47
47
|
## Callbacks order in case of different signals
|
data/docs/stats.md
CHANGED
|
@@ -55,24 +55,24 @@ 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.
|
|
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
|
-
|
|
62
|
+
This is a "wholistic" stat reflecting the overall current state of work to be done and the capacity to do it.
|
|
63
63
|
* pool_capacity: `how many threads are waiting to receive work` + `max_threads` - `running`. In a typical configuration where `min_threads`
|
|
64
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
65
|
and is not used for any internal decisions, unlike `busy_threads`, which is usually a more useful stat.
|
|
66
66
|
* max_threads: the maximum number of threads Puma is configured to spool per worker
|
|
67
67
|
* requests_count: the number of requests this worker has served since starting
|
|
68
|
-
* reactor_max: the maximum observed number of requests held in Puma's "reactor" which is used for
|
|
68
|
+
* reactor_max: the maximum observed number of requests held in Puma's "reactor" which is used for asynchronously buffering request bodies. This stat is reset on every call, so it's the maximum value observed since the last stat call.
|
|
69
69
|
* backlog_max: the maximum number of requests that have been fully buffered by the reactor and placed in a ready queue, but have not yet been picked up by a server thread. This stat is reset on every call, so it's the maximum value observed since the last stat call.
|
|
70
70
|
|
|
71
71
|
### cluster mode
|
|
72
72
|
|
|
73
73
|
* phase: which phase of restart the process is in, during [phased restart](https://github.com/puma/puma/blob/main/docs/restart.md)
|
|
74
74
|
* workers: ??
|
|
75
|
-
* booted_workers: how many workers currently running?
|
|
75
|
+
* booted_workers: how many workers are currently running?
|
|
76
76
|
* old_workers: ??
|
|
77
77
|
* worker_status: array of hashes of info for each worker (see below)
|
|
78
78
|
|
|
@@ -80,7 +80,7 @@ When Puma runs in single mode, these stats are available at the top level. When
|
|
|
80
80
|
|
|
81
81
|
* started_at: when the worker started
|
|
82
82
|
* pid: the process id of the worker process
|
|
83
|
-
* index: each worker gets a number.
|
|
83
|
+
* index: each worker gets a number. If Puma is configured to have 3 workers, then this will be 0, 1, or 2
|
|
84
84
|
* booted: if it's done booting [?]
|
|
85
85
|
* last_checkin: Last time the worker responded to the master process' heartbeat check.
|
|
86
86
|
* last_status: a hash of info about the worker's state handling requests. See the explanation for this in "single mode and individual workers in cluster mode" section above.
|
data/docs/systemd.md
CHANGED
|
@@ -30,6 +30,8 @@ After=network.target
|
|
|
30
30
|
Type=notify
|
|
31
31
|
|
|
32
32
|
# If your Puma process locks up, systemd's watchdog will restart it within seconds.
|
|
33
|
+
# Puma pings the watchdog as soon as it reports readiness, and every
|
|
34
|
+
# WatchdogSec/2 after that.
|
|
33
35
|
WatchdogSec=10
|
|
34
36
|
|
|
35
37
|
# Preferably configure a non-privileged user
|
|
@@ -71,7 +73,7 @@ for additional details.
|
|
|
71
73
|
systemd and Puma also support socket activation, where systemd opens the
|
|
72
74
|
listening socket(s) in advance and provides them to the Puma master process on
|
|
73
75
|
startup. Among other advantages, this keeps listening sockets open across puma
|
|
74
|
-
restarts and achieves graceful restarts, including when
|
|
76
|
+
restarts and achieves graceful restarts, including when upgrading Puma, and is
|
|
75
77
|
compatible with both cluster mode and application preload.
|
|
76
78
|
|
|
77
79
|
**Note:** Any wrapper scripts which `exec`, or other indirections in `ExecStart`
|
|
@@ -244,7 +246,7 @@ cap $stage puma:stop --dry-run
|
|
|
244
246
|
### Disabling Puma Systemd Integration
|
|
245
247
|
|
|
246
248
|
If you would like to disable Puma's systemd integration, for example if you handle it elsewhere
|
|
247
|
-
in your code yourself, simply set the
|
|
249
|
+
in your code yourself, simply set the environment variable `PUMA_SKIP_SYSTEMD` to any value.
|
|
248
250
|
|
|
249
251
|
|
|
250
252
|
|
|
@@ -78,7 +78,7 @@ ruby 3.2.0dev (2022-06-14T01:21:55Z master 048f14221c) +YJIT [x86_64-linux]
|
|
|
78
78
|
|
|
79
79
|
## bench_base.sh, bench_base.rb
|
|
80
80
|
|
|
81
|
-
These two files
|
|
81
|
+
These two files set up parameters for the Puma server, which is normally started in a shell
|
|
82
82
|
script. It then starts a Ruby file (a subclass of BenchBase), passing arguments to it. The
|
|
83
83
|
Ruby file is normally used to generate a client request stream(s).
|
|
84
84
|
|