diff --git a/lib/foreman/engine.rb b/lib/foreman/engine.rb index 71953fb..e1f1180 100644 --- a/lib/foreman/engine.rb +++ b/lib/foreman/engine.rb @@ -39,6 +39,22 @@ class Foreman::Engine spawn_processes watch_for_output watch_for_termination + terminate_gracefully + end + + def stop(name) + running_processes.each do |pid, process| + next unless process.name.start_with? name + + process.kill 'SIGTERM' + process = running_processes.delete(pid) + Timeout.timeout(5) do + begin + Process.waitpid(pid) + rescue Errno::ECHILD + end + end + end end def port_for(process, num, base_port=nil) @@ -91,6 +107,7 @@ private ###################################################################### rescue Timeout::Error info "sending SIGKILL to all processes" kill_all "SIGKILL" + rescue Errno::ECHILD end def poll_readers @@ -123,7 +140,6 @@ private ###################################################################### pid, status = Process.wait2 process = running_processes.delete(pid) info "process terminated", process.name - terminate_gracefully rescue Errno::ECHILD end diff --git a/spec/foreman/engine_spec.rb b/spec/foreman/engine_spec.rb index a7e8516..f64e5ba 100644 --- a/spec/foreman/engine_spec.rb +++ b/spec/foreman/engine_spec.rb @@ -35,6 +35,7 @@ describe "Foreman::Engine", :fakefs do mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./bravo", is_a(IO)) mock(subject).watch_for_output mock(subject).watch_for_termination + mock(subject).terminate_gracefully subject.start end @@ -45,6 +46,7 @@ describe "Foreman::Engine", :fakefs do mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./bravo", is_a(IO)).never mock(engine).watch_for_output mock(engine).watch_for_termination + mock(engine).terminate_gracefully engine.start end end @@ -109,6 +111,7 @@ describe "Foreman::Engine", :fakefs do it "should spawn" do stub(subject).watch_for_output stub(subject).watch_for_termination + stub(subject).terminate_gracefully subject.start Process.waitall mock(subject).info(/started with pid \d+/, "utf8.1", anything)