1

我在同一台服务器上有两个 Rails 应用程序,我们称它们为 A 和 B。

我正在尝试通过应用 B 自己的 capistrano 任务让应用 A 重新启动应用 B。不幸的是,即使在 cd-ing 到应用程序 B 的目录之后,它仍在尝试运行应用程序 A 的 capistrano。我错过了什么吗?

示例代码

system("cd /apps/appB/current && pwd && bundle exec cap:restart")

pwd 正确返回了 appB 的路径(/apps/appB/current),但是,其中有 cap:restart 的回溯。这是因为它仍在尝试在 appA 的上下文中运行 cap 命令,例如

/apps/appA/shared/bundle/ruby/1.9.1/gems/capistrano-2.15.4/lib/capistrano/configuration/loading.rb:152:in 'require': cannot load such file -- airbrake/capistrano (LoadError) from /apps/appA/shared/bundle/ruby/1.9.1/gems/capistrano-2.15.4/lib/capistrano/configuration/loading.rb:152:in 'require'.

我尝试不使用“bundle exec”,并尝试了其他一些进行系统调用的方法。我还在另一个目录中创建了一个 bash 脚本并尝试以这种方式运行它。

所描述的所有方法都表现出相同的行为。

您的帮助将不胜感激 =)

4

2 回答 2

1

您需要使用Bundler.with_clean_env以确保您的子进程不会选择您当前的 Bundler 环境:

Bundler.with_clean_env do
  system("cd /apps/appB/current && pwd && bundle exec cap:restart")
end

这与在其他 Rails 应用程序中安装 gem 包本质上是相同的问题

于 2013-08-09T07:20:44.570 回答
0

由于您说您的应用程序正在使用 Unicorn,因此您可以从应用程序 A 向应用程序 B 发出信号(或反之亦然)。

阅读此页面:http ://unicorn.bogomips.org/SIGNALS.html

每个应用程序唯一需要知道的是另一个应用程序的 pidfile 路径。所以看看你的独角兽配置,看看它在哪里存储。

您可以从该 pidfile 中读取 PID 并从 Ruby 中终止它:

pid = File.read(path_to_other_application_pidfile).chop
Process.kill("USR2", pid)

或者你可以使用反引号来执行 shell 命令

`kill -s USR2 \`cat #{path_to_other_application_pidfile}\``
于 2013-08-09T05:02:50.883 回答