Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

systemd - fix event firing #2591

Merged
merged 2 commits into from May 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 11 additions & 1 deletion lib/puma/cluster.rb
Expand Up @@ -43,6 +43,7 @@ def stop_workers
end

def start_phased_restart
@events.fire_on_restart!
@phase += 1
log "- Starting phased worker restart, phase: #{@phase}"

Expand Down Expand Up @@ -317,7 +318,7 @@ def setup_signals

stop_workers
stop

@events.fire_on_stopped!
raise(SignalException, "SIGTERM") if @options[:raise_exception_on_sigterm]
exit 0 # Clean exit, workers were stopped
end
Expand Down Expand Up @@ -411,12 +412,16 @@ def run

begin
booted = false
in_phased_restart = false
workers_not_booted = @options[:workers]

while @status == :run
begin
if @phased_restart
start_phased_restart
@phased_restart = false
in_phased_restart = true
workers_not_booted = @options[:workers]
end

check_workers
Expand Down Expand Up @@ -444,6 +449,7 @@ def run
w.boot!
log "- Worker #{w.index} (PID: #{pid}) booted in #{w.uptime.round(2)}s, phase: #{w.phase}"
@next_check = Time.now
workers_not_booted -= 1
when "e"
# external term, see worker method, Signal.trap "SIGTERM"
w.instance_variable_set :@term, true
Expand All @@ -461,6 +467,10 @@ def run
log "! Out-of-sync worker list, no #{pid} worker"
end
end
if in_phased_restart && workers_not_booted.zero?
@events.fire_on_booted!
in_phased_restart = false
end

rescue Interrupt
@status = :stop
Expand Down
45 changes: 33 additions & 12 deletions test/test_integration_systemd.rb
Expand Up @@ -31,21 +31,18 @@ def teardown
ENV["WATCHDOG_USEC"] = nil
end

def socket_message
@socket.recvfrom(15)[0]
def test_systemd_notify_usr1_phased_restart_cluster
skip_unless :fork
assert_restarts_with_systemd :USR1
end

def test_systemd_integration
cli_server "test/rackup/hello.ru"
assert_equal(socket_message, "READY=1")

connection = connect
restart_server connection
assert_equal(socket_message, "RELOADING=1")
assert_equal(socket_message, "READY=1")
def test_systemd_notify_usr2_hot_restart_cluster
skip_unless :fork
assert_restarts_with_systemd :USR2
end

stop_server
assert_equal(socket_message, "STOPPING=1")
def test_systemd_notify_usr2_hot_restart_single
assert_restarts_with_systemd :USR2, workers: 0
end

def test_systemd_watchdog
Expand All @@ -59,4 +56,28 @@ def test_systemd_watchdog
stop_server
assert_match(socket_message, "STOPPING=1")
end

private

def assert_restarts_with_systemd(signal, workers: 2)
cli_server "-w#{workers} test/rackup/hello.ru"
assert_equal socket_message, 'READY=1'

Process.kill signal, @pid
connect.write "GET / HTTP/1.1\r\n\r\n"
assert_equal socket_message, 'RELOADING=1'
assert_equal socket_message, 'READY=1'

Process.kill signal, @pid
connect.write "GET / HTTP/1.1\r\n\r\n"
assert_equal socket_message, 'RELOADING=1'
assert_equal socket_message, 'READY=1'

stop_server
assert_equal socket_message, 'STOPPING=1'
end

def socket_message
@socket.recvfrom(15)[0]
end
end