Pregunta

I have an application running with Flask, and use Compass as css preprocessor. Which means I need to start the python server and compass for development. I made what I thought was a clever Rakefile to start everything from one command and have everything run in only one terminal window.

Everything works, but the problem is when I try to stop everything (with cmd + c), it only kills the compass task and the Flask server keeps running. How can I make sure every tasks are stopped? Or is there an alternative to simultaneously launch several tasks without this issue?

Here is my rakefile, pretty simple:

# start compass
task :compass do
  system "compass watch"
end

# start the flask server
task :python do
  system "./server.py"
end

# open the browser once everything is ready
task :open do
  `open "http://127.0.0.1:5000"`
end

# the command I run: `$ rake server`
multitask :server => ['compass', 'python', 'open']

EDIT

For the record, I was using a Makefile and everything worked perfectly. But I changed part of my workflow and started using a Rakefile, so I Rakefile'd everything and got rid of the Makefile for simplicity.

¿Fue útil?

Solución

That is because system creates new processes for your commands. To make sure they are killed alongside your ruby process, you will need to kill them yourself. For this you need to know their process ids, which system does not provide, but spawn does. Then you can wait for them to exit, or kill the sub-processes when you hit ^C.

An example:

pids = []

task :foo do
  pids << spawn("sleep 3; echo foo")
end
task :bar do
  pids << spawn("sleep 3; echo bar")
end

desc "run"
multitask :run => [:foo, :bar] do
  begin
    puts "run"
    pids.each { |pid| Process.waitpid(pid) }
  rescue
    pids.each { |pid| Process.kill("TERM", pid) }
    exit
  end
end

If you do a rake run on that, the commands get executed, but when you abort, the tasks are sent the TERM signal. There's still an exception that makes it to the top level, but I guess for a Rakefile that is not meant to be published that does not matter too much. Waiting for the processes is necessary or the ruby process will finish before the others and the pids are lost (or have to be dug out of ps).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top