diff --git a/lib/puma/dsl.rb b/lib/puma/dsl.rb index 9dd3c2d475..c6a1ade17c 100644 --- a/lib/puma/dsl.rb +++ b/lib/puma/dsl.rb @@ -492,6 +492,28 @@ def after_worker_fork(&block) alias_method :after_worker_boot, :after_worker_fork + # When `fork_worker` is enabled, code to run in Worker 0 + # before all other workers are re-forked from this process, + # after the server has temporarily stopped serving requests + # (once per complete refork cycle). + # + # This can be used to trigger extra garbage-collection to maximize + # copy-on-write efficiency, or close any connections to remote servers + # (database, Redis, ...) that were opened while the server was running. + # + # This can be called multiple times to add several hooks. + # + # @note Cluster mode with `fork_worker` enabled only. + # @example + # on_refork do + # 3.times {GC.start} + # end + + def on_refork(&block) + @options[:before_refork] ||= [] + @options[:before_refork] << block + end + # Code to run out-of-band when the worker is idle. # These hooks run immediately after a request has finished # processing and there are no busy threads on the worker. diff --git a/test/helpers/integration.rb b/test/helpers/integration.rb index 0938bf6675..7234df7fe0 100644 --- a/test/helpers/integration.rb +++ b/test/helpers/integration.rb @@ -44,12 +44,18 @@ def teardown private - def cli_server(argv, unix: false) + def cli_server(argv, unix: false, config: nil) + if config + config_file = Tempfile.new(%w(config .rb)) + config_file.write config + config_file.close + config = "-C #{config_file.path}" + end if unix - cmd = "#{BASE} bin/puma -b unix://#{@bind_path} #{argv}" + cmd = "#{BASE} bin/puma #{config} -b unix://#{@bind_path} #{argv}" else @tcp_port = UniquePort.call - cmd = "#{BASE} bin/puma -b tcp://#{HOST}:#{@tcp_port} #{argv}" + cmd = "#{BASE} bin/puma #{config} -b tcp://#{HOST}:#{@tcp_port} #{argv}" end @server = IO.popen(cmd, "r") wait_for_server_to_boot diff --git a/test/test_integration_cluster.rb b/test/test_integration_cluster.rb index 79335a97fd..3f1176f573 100644 --- a/test/test_integration_cluster.rb +++ b/test/test_integration_cluster.rb @@ -157,13 +157,21 @@ def test_worker_timeout RUBY end + def test_refork + refork = Tempfile.new('refork') + cli_server "-w #{WORKERS} test/rackup/sleep.ru", config: <