2

我有一个使用 Flask 运行的应用程序,并使用 Compass 作为 css 预处理器。这意味着我需要启动 python 服务器和指南针进行开发。我制作了一个我认为很聪明的 Rakefile,从一个命令启动所有内容,并让所有内容仅在一个终端窗口中运行。

一切正常,但问题是当我尝试停止一切(使用cmd + c)时,它只会终止指南针任务并且 Flask 服务器继续运行。如何确保每个任务都停止?或者是否有替代方法可以同时启动多个任务而不会出现此问题?

这是我的 rakefile,非常简单:

# 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']

编辑

作为记录,我使用的是 Makefile 并且一切正常。但我改变了部分工作流程并开始使用 Rakefile,因此我对所有内容都进行了 Rakefile,并为了简单起见去掉了 Makefile。

4

1 回答 1

1

那是因为system为您的命令创建了新进程。为了确保它们在您的 ruby​​ 进程中被杀死,您需要自己杀死它们。为此,您需要知道他们的进程 ID,它system不提供,但提供spawn。然后你可以等待它们退出,或者当你点击 ^C 时终止子进程。

一个例子:

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

如果你这样做rake run,命令会被执行,但是当你中止时,任务会被发送 TERM 信号。仍然有一个例外可以使其达到最高级别,但我想对于一个不打算发布的 Rakefile 来说并不重要。等待进程是必要的,否则 ruby​​ 进程将在其他进程之前完成并且 pid 丢失(或必须被挖出ps)。

于 2013-09-16T19:54:54.173 回答