From 96fa81565cf1475009fb8c46fcbdeb92da977c6a Mon Sep 17 00:00:00 2001 From: Shayon Mukherjee Date: Fri, 4 Aug 2017 22:03:34 -0700 Subject: [PATCH] Return proper exit code for TERM signal Attempt at returning the proper exit code (128+15) when TERM signal is sent to the server, for both single and clustered mode. The changes are achieved by restoring signal from within the trap and accordingly killing the process using TERM event. Added plus, stopping single mode gracefully now. --- lib/puma/cluster.rb | 3 +++ lib/puma/launcher.rb | 5 ++++- test/test_integration.rb | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/puma/cluster.rb b/lib/puma/cluster.rb index d4c1957825..a02ed1ea8d 100644 --- a/lib/puma/cluster.rb +++ b/lib/puma/cluster.rb @@ -376,6 +376,9 @@ def setup_signals exit! 0 else stop + + Signal.trap("SIGTERM", "DEFAULT") + Process.kill("TERM", Process.pid) end end end diff --git a/lib/puma/launcher.rb b/lib/puma/launcher.rb index 48867b2c85..d6447a63b3 100644 --- a/lib/puma/launcher.rb +++ b/lib/puma/launcher.rb @@ -392,7 +392,10 @@ def setup_signals begin Signal.trap "SIGTERM" do - stop + graceful_stop + + Signal.trap("SIGTERM", "DEFAULT") + Process.kill("TERM", Process.pid) end rescue Exception log "*** SIGTERM not implemented, signal based gracefully stopping unavailable!" diff --git a/test/test_integration.rb b/test/test_integration.rb index e431381e05..1f9fa37b0c 100644 --- a/test/test_integration.rb +++ b/test/test_integration.rb @@ -53,6 +53,21 @@ def server(argv) @server end + def start_forked_server(argv) + pid = fork do + exec "#{Gem.ruby} -I lib/ bin/puma -b tcp://127.0.0.1:#{@tcp_port} #{argv}" + end + + sleep 5 + pid + end + + def stop_forked_server(pid) + Process.kill(:TERM, pid) + sleep 1 + Process.wait2(pid) + end + def restart_server_and_listen(argv) skip_on_appveyor server(argv) @@ -218,4 +233,22 @@ def test_restart_restores_environment assert_includes new_reply, "Hello RAND" refute_equal initial_reply, new_reply end + + def test_term_signal_exit_code_in_single_mode + skip if Puma.jruby? || Puma.windows? + + pid = start_forked_server("test/rackup/hello.ru") + _, status = stop_forked_server(pid) + + assert_equal 15, status + end + + def test_term_signal_exit_code_in_clustered_mode + skip if Puma.jruby? || Puma.windows? + + pid = start_forked_server("-w 2 test/rackup/hello.ru") + _, status = stop_forked_server(pid) + + assert_equal 15, status + end end