如何在后台启动脚本并记录到特定文件并完全从ruby中分离?

时间:2017-11-21 09:01:31

标签: ruby-on-rails ruby sidekiq

我有一些ruby代码(sidekiq作业),如下所示:

module WorkerJobs
  class MyJob < SidekiqWorker

    def perform country
      # Exec, ``, system, Spawn ... whatever?
      # ????
    end

  end
end

我想让ruby代码启动这样的命令(需要几个小时才能完成):

"cd ~/my_dir/production && nohub Rscript --vanilla main.r --country #{country} > /home/deployer/my_dir/shared/log/log_#{country}.log 2>&1 &"

目标是让脚本启动并完成sidekiq作业而不等待任何事情(因为脚本需要几个小时才能运行),因此sidekiq可以继续前进并完成其他工作。 Sidekiq / ruby​​不需要知道工作状态的任何细节。

我尝试使用system()但是由于某种原因,似乎没有将stdout / err发送到指定的日志文件?我试着阅读有关执行脚本的其他方法,但我无法弄清楚在这种情况下哪种方法是正确的。同样,当脚本运行启动的sidekiq进程/线程时,它可能会停止/启动/执行 - 它应该不会影响脚本

1 个答案:

答案 0 :(得分:0)

好的,所以我最终选择了spawn

module WorkerJobs
  class MyJob < SidekiqWorker

    def perform country
      logfile =  "/home/deployer/my_dir/shared/log/log_#{country}.log"
      pid = spawn("cd ~/my_dir/production && nohub Rscript --vanilla main.r --country #{country}", [:out, :err] => logfile)
      Process.detach(pid)
    end

  end
end

按预期工作。

更新1

但现在发生了这种情况:How to debug R-script suddenly stopping at random point with no error?(相关或不相关的我不知道?)

更新2

它实际上似乎是相关的!当sidekiq重新启动(得到杀死-15)时,它也会破坏这个过程。奇怪......调查......

最终更新

事实证明,由于sidekiq是由systemd启动的,因此systemd实际上是负责处理任何“子”进程的人(无论他们是否真的是经典的子进程)。这是systemd的默认行为。可以在此处找到解释:Can't detach child process when main process is started from systemd

将系统d的killmode更改为process解决了问题。