From 169188376baa5b5d1b59c4636fbad51d461912ac Mon Sep 17 00:00:00 2001 From: Michael Granger Date: Mon, 4 Mar 2013 14:05:53 -0800 Subject: [PATCH] Try to allow children to shut down gracefully Since signals will no longer be handled once foreman goes into `terminate_gracefully`, default signal handlers are restored so as not to cause it to get stuck in an unTERMable state. This necessitates not using the process group for signalling except as a last resort, as foreman itself will receive the signals it sends. This splits `killall` into two methods, one which signals only processes foreman itself has started, and one which signals all processes in the process group to try to clean up more aggressively, and then reworks `terminate_gracefully` to use them. --- lib/foreman/engine.rb | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/foreman/engine.rb b/lib/foreman/engine.rb index 0fd7da5..7463e53 100644 --- a/lib/foreman/engine.rb +++ b/lib/foreman/engine.rb @@ -177,11 +177,11 @@ class Foreman::Engine end end - # Send a signal to all processesstarted by this +Engine+ + # Send a signal to all processes started by this +Engine+ # # @param [String] signal The signal to send to each process # - def killall(signal="SIGTERM") + def kill_children(signal="SIGTERM") if Foreman.windows? @running.each do |pid, (process, index)| system "sending #{signal} to #{name_for(pid)} at pid #{pid}" @@ -190,6 +190,21 @@ class Foreman::Engine rescue Errno::ESRCH, Errno::EPERM end end + else + begin + Process.kill signal, *@running.keys unless @running.empty? + rescue Errno::ESRCH, Errno::EPERM + end + end + end + + # Send a signal to the whole process group. + # + # @param [String] signal The signal to send + # + def killall(signal="SIGTERM") + if Foreman.windows? + kill_children(signal) else begin Process.kill "-#{signal}", Process.getpgrp @@ -402,10 +417,10 @@ private @terminating = true if Foreman.windows? system "sending SIGKILL to all processes" - killall "SIGKILL" + kill_children "SIGKILL" else system "sending SIGTERM to all processes" - killall "SIGTERM" + kill_children "SIGTERM" end Timeout.timeout(options[:timeout]) do watch_for_termination while @running.length > 0