Allow to use `preload_app!` with `fork_worker` (#2907)

So far it was incompatible because true phased
restart are incompatible with preload_app.

But `fork_worker` doesn't do a phased restart
per say, it just piggy back on the implementation
to ask worker #0 to refork its siblings.

So we can just bypass that check and it works.

Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
This commit is contained in:
Jean byroot Boussier 2022-09-15 03:30:55 +02:00 committed by GitHub
parent 317e890351
commit e438b907de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 4 additions and 6 deletions

View File

@ -10,7 +10,7 @@ Puma 5 introduces an experimental new cluster-mode configuration option, `fork_w
10004 \_ puma: cluster worker 3: 10000 [puma]
```
Similar to the `preload_app!` option, the `fork_worker` option allows your application to be initialized only once for copy-on-write memory savings, and it has two additional advantages:
The `fork_worker` option allows your application to be initialized only once for copy-on-write memory savings, and it has two additional advantages:
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.
@ -24,8 +24,6 @@ Similar to the `preload_app!` option, the `fork_worker` option allows your appli
### Limitations
- Not compatible with the `preload_app!` option
- This mode is still very experimental so there may be bugs or edge-cases, particularly around expected behavior of existing hooks. Please open a [bug report](https://github.com/puma/puma/issues/new?template=bug_report.md) if you encounter any issues.
- 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.

View File

@ -213,8 +213,8 @@ module Puma
stop
end
def phased_restart
return false if @options[:preload_app]
def phased_restart(refork = false)
return false if @options[:preload_app] && !refork
@phased_restart = true
wakeup!
@ -281,7 +281,7 @@ module Puma
if (worker = @workers.find { |w| w.index == 0 })
worker.phase += 1
end
phased_restart
phased_restart(true)
end
# We do this in a separate method to keep the lambda scope