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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +115 -0
  3. data/README.md +20 -5
  4. data/docs/6.0-Upgrade.md +1 -1
  5. data/docs/8.0-Upgrade.md +2 -2
  6. data/docs/deployment.md +3 -3
  7. data/docs/fork_worker.md +34 -4
  8. data/docs/kubernetes.md +3 -3
  9. data/docs/plugins.md +2 -2
  10. data/docs/puma_support.md +78 -0
  11. data/docs/rails_dev_mode.md +2 -2
  12. data/docs/restart.md +4 -3
  13. data/docs/signals.md +2 -2
  14. data/docs/stats.md +5 -5
  15. data/docs/systemd.md +4 -2
  16. data/docs/testing_benchmarks_local_files.md +1 -1
  17. data/docs/testing_test_rackup_ci_files.md +2 -2
  18. data/ext/puma_http11/extconf.rb +2 -0
  19. data/ext/puma_http11/http11_parser.c +6 -2
  20. data/ext/puma_http11/http11_parser_common.rl +4 -1
  21. data/ext/puma_http11/mini_ssl.c +8 -4
  22. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +36 -36
  23. data/ext/puma_http11/puma_http11.c +24 -0
  24. data/lib/puma/binder.rb +29 -0
  25. data/lib/puma/cli.rb +6 -0
  26. data/lib/puma/client.rb +75 -29
  27. data/lib/puma/client_env.rb +32 -18
  28. data/lib/puma/cluster/worker.rb +109 -33
  29. data/lib/puma/cluster/worker_handle.rb +16 -0
  30. data/lib/puma/cluster.rb +173 -44
  31. data/lib/puma/commonlogger.rb +3 -3
  32. data/lib/puma/configuration.rb +22 -3
  33. data/lib/puma/const.rb +11 -9
  34. data/lib/puma/dsl.rb +265 -91
  35. data/lib/puma/launcher.rb +6 -4
  36. data/lib/puma/minissl.rb +1 -1
  37. data/lib/puma/plugin/systemd.rb +1 -1
  38. data/lib/puma/puma_http11.jar +0 -0
  39. data/lib/puma/response.rb +13 -5
  40. data/lib/puma/runner.rb +5 -1
  41. data/lib/puma/sd_notify.rb +4 -1
  42. data/lib/puma/server.rb +45 -20
  43. data/lib/puma/thread_pool.rb +12 -1
  44. data/lib/puma.rb +1 -1
  45. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9bb993a39d400591f128b4808ca9d7f735618d614f6e490f850838ac7121391c
4
- data.tar.gz: aae15617fcd8cd7147701e1f594625554bc6178c991c5ee98e00ca5bc0d1346d
3
+ metadata.gz: 3e02c432552f5eaaac8c58b225f9f0dd3c22989934edd82cd1fb1bd29b5ba363
4
+ data.tar.gz: 64bc20c3349c3de9518aa40131410effa3d4bf7f7c6e5e761be5a1e9b13e0af9
5
5
  SHA512:
6
- metadata.gz: 2a47f4ca7106a37810eff02f38a0a7410904fa78bf3e9022176cc2d09eea261bb622f18b5d2a8f9e3330404850a2f5a2cd5178e5b65d2f78aab222c7faf1a467
7
- data.tar.gz: db545b9e393c0236856a6db02e8b1953cd6eb19a41573aab67ff766f67fa65ba90e4e8d4984b9653481cfb834dc29d585aa94cc657adab31ce05d6a5d6ae5614
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
  [![Actions](https://github.com/puma/puma/actions/workflows/tests.yml/badge.svg?branch=main)](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&amp;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 &amp; 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 is an `before_refork` and `after_refork` hooks which are used only in [`fork_worker` mode](docs/fork_worker.md),
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 when it receives
229
- # a stop command but before it shuts down.
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 incompatibilites.
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 by 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.
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 [[the support table in the PR](https://github.com/puma/puma/pull/3847)](https://github.com/puma/puma/pull/3847) for a 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.
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:DR;**: 80% of Puma apps will end up deploying "pods" of 4 workers, 5 threads each, 4 vCPU and 8GB of RAM.
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
- Puma 5 introduces an experimental new cluster-mode configuration option, `fork_worker` (`--fork-worker` from the CLI). This mode causes Puma to fork additional workers from worker 0, instead of directly from the master process:
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 4.3.3 (tcp://0.0.0.0:9292) [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.** Because the master process itself doesn't preload the application, 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.
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 to copy 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.
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 pods pre-stop hook get called. The default for this is to send `SIGTERM` to the process inside the pod.
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 step 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 pods' 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.
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 way 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.
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, activating the `heroku`
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 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).
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
+
@@ -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), work poorly with any multi-process web server.
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` mode.
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. if this is frequently 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.
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 asyncronously buffering request bodies. This stat is reset on every call, so it's the maximum value observed since the last stat call.
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. if Puma is configured to have 3 workers, then this will be 0, 1, or 2
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 upgraded Puma, and is
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 the environment variable `PUMA_SKIP_SYSTEMD` to any value.
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 setup parameters for the Puma server, which is normally started in a shell
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