我有一个主工作者架构,工人数量每周都在增长。我不能再期望ssh或远程控制台进入每台机器杀死工作人员,执行源代码控制同步,并重新启动。我希望能够让主人在网络上发出一条消息,告诉每台机器同步并重启。
这就是我遇到障碍的地方。如果我使用任何理智的平台,我可以这样做:
exec('ruby', __FILE__)
......并且完成了。但是,我做了以下测试:
p Process.pid
sleep 1
exec('ruby', __FILE__)
...在Windows上,每次调用exec时都会得到一个ruby实例。在我遇到有问题的窗口上的^ C之前,他们都没有死。在我尝试过的每个平台上,它每次都在执行新版本的文件,我通过对测试脚本进行简单的编辑来验证这一点,同时测试结果也是如此。
我打印pid的原因是要仔细检查我看到的行为。在Windows上,我每次执行时都会得到一个不同的pid - 考虑到我在每次运行的任务管理器中都看到了一个新进程。 mac的行为正确:每个系统调用的pid都是相同的,我已经用dtrace验证每次运行是否触发对execve系统调用的调用。
那么,简而言之,有没有办法让Windows ruby脚本重新启动它的执行,这样它就会运行任何代码 - 包括它自己 - 在执行过程中发生了变化?请注意,这不是rails应用程序,但它确实使用了activerecord。
答案 0 :(得分:2)
在尝试了一些解决方案(包括拜伦·惠特洛克提交的解决方案,最终让我走上了令人满意的目标之路)后,我决定:
IO.popen("start cmd /C ruby.exe #{$0} #{ARGV.join(' ')}")
sleep 5
我发现,如果我在popen之后根本没有睡觉,并且刚刚退出,那么产卵会经常(> 50%的时间)失败。这显然不是跨平台的,所以为了在mac上具有相同的行为:
IO.popen("xterm -e \"ruby blah blah blah\"&")
答案 1 :(得分:0)
重新启动程序的经典方法是编写另一个为您执行此操作的方法。所以你将一个过程产生到restart.exe <args>
,然后死掉或退出; restart.exe等待,直到调用脚本不再运行,然后再次启动脚本。