Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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.
  • Loading branch information...
commit 169188376baa5b5d1b59c4636fbad51d461912ac 1 parent 5ab08c6
@ged ged authored
Showing with 19 additions and 4 deletions.
  1. +19 −4 lib/foreman/engine.rb
View
23 lib/foreman/engine.rb
@@ -177,11 +177,11 @@ def load_env(filename)
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}"
@@ -192,6 +192,21 @@ def killall(signal="SIGTERM")
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
rescue Errno::ESRCH, Errno::EPERM
end
@@ -402,10 +417,10 @@ def terminate_gracefully
@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
Please sign in to comment.
Something went wrong with that request. Please try again.