DEV: handle termination cleanly in autospec

This commit is contained in:
Sam 2018-06-18 13:20:23 +10:00
parent 91b73e0c2d
commit cc3fc87dd7
4 changed files with 52 additions and 14 deletions

View File

@ -30,7 +30,15 @@ class Autospec::Manager
def run
Signal.trap("HUP") { stop_runners; exit }
Signal.trap("INT") { stop_runners; exit }
Signal.trap("INT") do
begin
stop_runners
rescue => e
puts "FAILED TO STOP RUNNERS #{e}"
end
exit
end
ensure_all_specs_will_run
start_runners

View File

@ -3,11 +3,16 @@ require "autospec/rspec_runner"
module Autospec
class SimpleRunner < RspecRunner
def initialize
@mutex = Mutex.new
end
def run(specs)
puts "Running Rspec: " << specs
# kill previous rspec instance
self.abort
@mutex.synchronize do
self.abort
end
# we use our custom rspec formatter
args = ["-r", "#{File.dirname(__FILE__)}/formatter.rb",
"-f", "Autospec::Formatter", specs.split].flatten.join(" ")
@ -18,24 +23,42 @@ module Autospec
env["LOAD_PLUGINS"] = "1"
puts "Loading plugins while running specs"
end
@pid = Process.spawn(env, "bin/rspec #{args}")
_, status = Process.wait2(@pid)
pid =
@mutex.synchronize do
@pid = Process.spawn(env, "bin/rspec #{args}")
end
_, status = Process.wait2(pid)
status.exitstatus
end
end
def abort
if @pid
Process.kill("INT", @pid) rescue nil
while (Process.getpgid(@pid) rescue nil)
sleep 0.001
end
@pid = nil
if pid = @pid
Process.kill("TERM", pid) rescue nil
wait_for_done(pid)
pid = nil
end
end
def stop
abort
# assume sigint on child will take care of this?
if pid = @pid
wait_for_done(pid)
end
end
def wait_for_done(pid)
i = 3000
while (i > 0 && Process.getpgid(pid) rescue nil)
sleep 0.001
i -= 1
end
if (Process.getpgid(pid) rescue nil)
STDERR.puts "Terminating rspec #{pid} by force cause it refused graceful termination"
Process.kill("KILL", pid)
end
end
end

View File

@ -61,11 +61,14 @@ class Demon::Base
end
end
def stop_signal
"HUP"
end
def stop
@started = false
if @pid
# TODO configurable stop signal
Process.kill("HUP", @pid)
Process.kill(stop_signal, @pid)
wait_for_stop = lambda {
timeout = @stop_timeout
@ -82,7 +85,7 @@ class Demon::Base
wait_for_stop.call
if alive?
STDERR.puts "Process would not terminate cleanly, force quitting. pid: #{@pid}"
STDERR.puts "Process would not terminate cleanly, force quitting. pid: #{@pid} #{self.class}"
Process.kill("KILL", @pid)
end

View File

@ -6,6 +6,10 @@ class Demon::RailsAutospec < Demon::Base
"rails-autospec"
end
def stop_signal
"TERM"
end
private
def after_fork