From 137a80d766478ba03f5c5fecbe152a2b26ee2359 Mon Sep 17 00:00:00 2001 From: Shayon Mukherjee Date: Wed, 16 Aug 2017 08:23:51 -0700 Subject: [PATCH] Return proper exit code for TERM signal (#1337) 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 | 4 +++- test/test_integration.rb | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/puma/cluster.rb b/lib/puma/cluster.rb index d4c1957825..9976103eba 100644 --- a/lib/puma/cluster.rb +++ b/lib/puma/cluster.rb @@ -375,7 +375,10 @@ def setup_signals log "Early termination of worker" exit! 0 else + stop_workers stop + + raise SignalException, "SIGTERM" end end end diff --git a/lib/puma/launcher.rb b/lib/puma/launcher.rb index 5ec7bc5308..6b6cb17ad9 100644 --- a/lib/puma/launcher.rb +++ b/lib/puma/launcher.rb @@ -392,7 +392,9 @@ def setup_signals begin Signal.trap "SIGTERM" do - stop + graceful_stop + + raise SignalException, "SIGTERM" 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