Revert "Merge pull request #176 from rtyler/feature/156-foreman-stop-command"
Rewriting using a better Process API This reverts commitdbe51832b0, reversing changes made to69216b4c5e.
This commit is contained in:
1 parent
dbe51832b0
commit
0b34f067cb
4 files changed
+41
-58
No files matched your search
+1
-1
@@ -30,7 +30,7 @@ class Foreman::CLI < Thor
|
|||||||
def start(process=nil)
|
def start(process=nil)
|
||||||
check_procfile!
|
check_procfile!
|
||||||
engine.options[:concurrency] = "#{process}=1" if process
|
engine.options[:concurrency] = "#{process}=1" if process
|
||||||
engine.run
|
engine.start
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "export FORMAT LOCATION", "Export the application to another process management format"
|
desc "export FORMAT LOCATION", "Export the application to another process management format"
|
||||||
|
|||||||
+31
-45
@@ -28,7 +28,7 @@ class Foreman::Engine
|
|||||||
@output_mutex = Mutex.new
|
@output_mutex = Mutex.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def start
|
||||||
proctitle "ruby: foreman master"
|
proctitle "ruby: foreman master"
|
||||||
termtitle "#{File.basename(@directory)} - foreman"
|
termtitle "#{File.basename(@directory)} - foreman"
|
||||||
|
|
||||||
@@ -36,49 +36,9 @@ class Foreman::Engine
|
|||||||
trap("INT") { puts "SIGINT received"; terminate_gracefully }
|
trap("INT") { puts "SIGINT received"; terminate_gracefully }
|
||||||
|
|
||||||
assign_colors
|
assign_colors
|
||||||
start
|
spawn_processes
|
||||||
watch_for_output
|
watch_for_output
|
||||||
watch_for_termination
|
watch_for_termination
|
||||||
terminate_gracefully
|
|
||||||
end
|
|
||||||
|
|
||||||
def start(name=nil)
|
|
||||||
concurrency = Foreman::Utils.parse_concurrency(@options[:concurrency])
|
|
||||||
|
|
||||||
procfile.entries.each do |entry|
|
|
||||||
unless name == nil
|
|
||||||
next unless entry.name == name
|
|
||||||
end
|
|
||||||
|
|
||||||
reader, writer = (IO.method(:pipe).arity == 0 ? IO.pipe : IO.pipe("BINARY"))
|
|
||||||
entry.spawn(concurrency[entry.name], writer, @directory, @environment, port_for(entry, 1, base_port)).each do |process|
|
|
||||||
running_processes[process.pid] = process
|
|
||||||
readers[process] = reader
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def stop(name=nil, signal='SIGTERM')
|
|
||||||
running_processes.each do |pid, process|
|
|
||||||
unless name == ALL_PROCESSES
|
|
||||||
# Comparing against process.entry.name instead of process.name to
|
|
||||||
# make sure we match the process name exactly for any/all
|
|
||||||
# concurrently running processes by this name
|
|
||||||
next unless process.entry.name == name
|
|
||||||
else
|
|
||||||
info "sending #{signal} to all processes"
|
|
||||||
end
|
|
||||||
|
|
||||||
process.kill signal
|
|
||||||
process = running_processes.delete(pid)
|
|
||||||
Timeout.timeout(5) do
|
|
||||||
begin
|
|
||||||
Process.waitpid(pid)
|
|
||||||
info "process terminated", process.name
|
|
||||||
rescue Errno::ECHILD
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def port_for(process, num, base_port=nil)
|
def port_for(process, num, base_port=nil)
|
||||||
@@ -93,19 +53,44 @@ class Foreman::Engine
|
|||||||
|
|
||||||
private ######################################################################
|
private ######################################################################
|
||||||
|
|
||||||
|
def spawn_processes
|
||||||
|
concurrency = Foreman::Utils.parse_concurrency(@options[:concurrency])
|
||||||
|
|
||||||
|
procfile.entries.each do |entry|
|
||||||
|
reader, writer = (IO.method(:pipe).arity == 0 ? IO.pipe : IO.pipe("BINARY"))
|
||||||
|
entry.spawn(concurrency[entry.name], writer, @directory, @environment, port_for(entry, 1, base_port)).each do |process|
|
||||||
|
running_processes[process.pid] = process
|
||||||
|
readers[process] = reader
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def base_port
|
def base_port
|
||||||
options[:port] || 5000
|
options[:port] || 5000
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def kill_all(signal="SIGTERM")
|
||||||
|
running_processes.each do |pid, process|
|
||||||
|
info "sending #{signal} to pid #{pid}"
|
||||||
|
process.kill signal
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def terminate_gracefully
|
def terminate_gracefully
|
||||||
return if @terminating
|
return if @terminating
|
||||||
@terminating = true
|
@terminating = true
|
||||||
|
info "sending SIGTERM to all processes"
|
||||||
|
kill_all "SIGTERM"
|
||||||
Timeout.timeout(5) do
|
Timeout.timeout(5) do
|
||||||
stop
|
while running_processes.length > 0
|
||||||
|
pid, status = Process.wait2
|
||||||
|
process = running_processes.delete(pid)
|
||||||
|
info "process terminated", process.name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
rescue Timeout::Error
|
rescue Timeout::Error
|
||||||
stop(nil, 'SIGKILL')
|
info "sending SIGKILL to all processes"
|
||||||
rescue Errno::ECHILD
|
kill_all "SIGKILL"
|
||||||
end
|
end
|
||||||
|
|
||||||
def poll_readers
|
def poll_readers
|
||||||
@@ -138,6 +123,7 @@ private ######################################################################
|
|||||||
pid, status = Process.wait2
|
pid, status = Process.wait2
|
||||||
process = running_processes.delete(pid)
|
process = running_processes.delete(pid)
|
||||||
info "process terminated", process.name
|
info "process terminated", process.name
|
||||||
|
terminate_gracefully
|
||||||
rescue Errno::ECHILD
|
rescue Errno::ECHILD
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ describe "Foreman::CLI", :fakefs do
|
|||||||
|
|
||||||
it "runs successfully" do
|
it "runs successfully" do
|
||||||
dont_allow(subject).error
|
dont_allow(subject).error
|
||||||
mock.instance_of(Foreman::Engine).run
|
mock.instance_of(Foreman::Engine).start
|
||||||
subject.start
|
subject.start
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -28,15 +28,14 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "run" do
|
describe "start" do
|
||||||
it "forks the processes" do
|
it "forks the processes" do
|
||||||
write_procfile
|
write_procfile
|
||||||
mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./alpha", is_a(IO))
|
mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./alpha", is_a(IO))
|
||||||
mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./bravo", is_a(IO))
|
mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./bravo", is_a(IO))
|
||||||
mock(subject).watch_for_output
|
mock(subject).watch_for_output
|
||||||
mock(subject).watch_for_termination
|
mock(subject).watch_for_termination
|
||||||
mock(subject).terminate_gracefully
|
subject.start
|
||||||
subject.run
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "handles concurrency" do
|
it "handles concurrency" do
|
||||||
@@ -46,8 +45,7 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./bravo", is_a(IO)).never
|
mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./bravo", is_a(IO)).never
|
||||||
mock(engine).watch_for_output
|
mock(engine).watch_for_output
|
||||||
mock(engine).watch_for_termination
|
mock(engine).watch_for_termination
|
||||||
mock(engine).terminate_gracefully
|
engine.start
|
||||||
engine.run
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -57,7 +55,7 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
stub(Process).fork
|
stub(Process).fork
|
||||||
any_instance_of(Foreman::Engine) do |engine|
|
any_instance_of(Foreman::Engine) do |engine|
|
||||||
stub(engine).info
|
stub(engine).info
|
||||||
stub(engine).start
|
stub(engine).spawn_processes
|
||||||
stub(engine).watch_for_termination
|
stub(engine).watch_for_termination
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -66,7 +64,7 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
|
File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
|
||||||
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
|
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
|
||||||
engine.environment.should == {"FOO"=>"baz"}
|
engine.environment.should == {"FOO"=>"baz"}
|
||||||
engine.run
|
engine.start
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should read more than one if specified" do
|
it "should read more than one if specified" do
|
||||||
@@ -74,7 +72,7 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") }
|
File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") }
|
||||||
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env1,/tmp/env2")
|
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env1,/tmp/env2")
|
||||||
engine.environment.should == { "FOO"=>"bar", "BAZ"=>"qux" }
|
engine.environment.should == { "FOO"=>"bar", "BAZ"=>"qux" }
|
||||||
engine.run
|
engine.start
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should handle quoted values" do
|
it "should handle quoted values" do
|
||||||
@@ -97,7 +95,7 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
File.open(".env", "w") { |f| f.puts("FOO=qoo") }
|
File.open(".env", "w") { |f| f.puts("FOO=qoo") }
|
||||||
engine = Foreman::Engine.new("Procfile")
|
engine = Foreman::Engine.new("Procfile")
|
||||||
engine.environment.should == {"FOO"=>"qoo"}
|
engine.environment.should == {"FOO"=>"qoo"}
|
||||||
engine.run
|
engine.start
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -111,8 +109,7 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
it "should spawn" do
|
it "should spawn" do
|
||||||
stub(subject).watch_for_output
|
stub(subject).watch_for_output
|
||||||
stub(subject).watch_for_termination
|
stub(subject).watch_for_termination
|
||||||
stub(subject).terminate_gracefully
|
subject.start
|
||||||
subject.run
|
|
||||||
Process.waitall
|
Process.waitall
|
||||||
mock(subject).info(/started with pid \d+/, "utf8.1", anything)
|
mock(subject).info(/started with pid \d+/, "utf8.1", anything)
|
||||||
mock(subject).info("\xff\x03\n", "utf8.1", anything)
|
mock(subject).info("\xff\x03\n", "utf8.1", anything)
|
||||||
|
|||||||
Reference in new issue
Block a user