2

我有一个 master-workers 架构,其中工人的数量每周都在增长。不能再期望我通过 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。

4

2 回答 2

2

在尝试了许多解决方案(包括 Byron Whitlock 提交的解决方案,它最终让我走上了圆满结束的道路)后,我决定:

IO.popen("start cmd /C ruby.exe #{$0} #{ARGV.join(' ')}")
sleep 5

我发现如果我在 popen 之后根本不睡觉,只是退出,那么 spawn 会经常(>50% 的时间)失败。这显然不是跨平台的,因此为了在 mac 上具有相同的行为:

IO.popen("xterm -e \"ruby blah blah blah\"&")
于 2010-04-16T21:04:33.377 回答
0

重新启动程序的经典方法是编写另一个为您执行此操作的程序。所以你产生一个进程restart.exe <args>,然后死亡或退出;restart.exe 等到调用脚本不再运行,然后再次启动脚本。

于 2010-04-13T23:25:27.920 回答