1
0
Fork 0
mirror of https://github.com/puma/puma.git synced 2022-11-09 13:48:40 -05:00

Add on_refork hook configuration and integration test

This commit is contained in:
Will Jordan 2020-05-04 13:52:20 -07:00
parent 0c25b37bf5
commit 0e2fec51e4
3 changed files with 43 additions and 7 deletions

View file

@ -492,6 +492,28 @@ module Puma
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.

View file

@ -44,12 +44,18 @@ class TestIntegration < Minitest::Test
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

View file

@ -157,13 +157,21 @@ end
RUBY
end
def test_refork
refork = Tempfile.new('refork')
cli_server "-w #{WORKERS} test/rackup/sleep.ru", config: <<RUBY
fork_worker 1
on_refork {File.write('#{refork.path}', 'Reforked')}
RUBY
pids = get_worker_pids
read_body(connect('sleep1')) until refork.read == 'Reforked'
refute_includes pids, get_worker_pids(1, WORKERS - 1)
end
private
def worker_timeout(timeout, iterations, config)
config_file = Tempfile.new(%w(worker_timeout .rb))
config_file.write config
config_file.close
cli_server "-w #{WORKERS} -t 1:1 -C #{config_file.path} test/rackup/hello.ru"
cli_server "-w #{WORKERS} -t 1:1 test/rackup/hello.ru", config: config
pids = []
Timeout.timeout(iterations * timeout + 1) do