【问题标题】:Interrupt Rails Server Output w/o Stopping the Server during a Capistrano Deployment在 Capistrano 部署期间中断 Rails 服务器输出,无需停止服务器
【发布时间】:2012-07-09 06:37:37
【问题描述】:

我正在对 Rails 应用程序进行 Capistrano 部署。大部分时间都很有趣。

部署完成后(在deploy:restart),我想启动Rails服务器,观察一段时间的输出,然后点击Ctrl-C发送中断,从而停止输出,然后继续deploy:cleanup 任务。在某一时刻,这似乎是有效的,只是它似乎将中断视为一个异常,因此即使它实际上已启动并正在运行,它也会说“无法启动 Rails 服务器”。我想挽救中断,所以写了以下内容,部分基于another thread here:

namespace :deploy do
    task :restart, :roles => :app, :except => { :no_release => true } do 
      begin
        logger.info 'Attempting to Start the Rails Server'
        run "cd #{release_path} && script/rails s"
      rescue SystemExit, Interrupt
        logger.info %q[Au revoir! And don't worry. The server will continue running just fine without you hanging around looking over it's shoulder.]
      rescue Exception => error
        logger.important 'Cannot Start the Rails Server. This may be a problem.'
        logger.info "#{error}"
      end
    end
  end

但是,这不起作用。在我按下 Ctrl-C 之前,当服务器仍在运行时,正如我所料,我得到了这样的东西:

 ** [out :: server.example.com] Started GET "/assets/bootstrap.js?body=1" for 178.120.25.53 at 2012-07-09 19:10:53 +0000
 ** [out :: server.example.com] Served asset /bootstrap.js - 200 OK (11ms)

然后在我发送中断后,我得到了这个:

 ** Au revoir! And don't worry. The server will continue running just fine without you hanging around looking over it's shoulder.
    triggering after callbacks for `deploy:restart'
  * executing `deploy:cleanup'
  * executing "ls -xt /srv/www/my_project/releases"
    servers: ["server.example.com"]
    [server.example.com] executing command
    command finished in 774ms
 ** keeping 1 of 2 deployed releases
  * executing "rm -rf /srv/www/my_project/releases/20120709190209"
    servers: ["server.example.com"]
    [server.example.com] executing command
    command finished in 811ms

这看起来是对的……但事实证明,Rails 实际上并没有在运行,正如 grep 之前和之后的进程所揭示的那样。

在Ctrl-C 之前,我看到了 Capistrano 命令 (19358) 和它启动的 Rails 服务器 (19507):

user@server.example.com:~$ ps ax | grep rails | grep -v grep
19358 pts/1    Ss+  0:01 bash -c cd /srv/www/my_project/releases/20120709190521 && script/rails s
19507 pts/1    Sl+  0:41 ruby script/rails s

在Ctrl-C 之后,Rails 服务器仍然在那里,或者看起来是:

user@server.example.com:~$ ps ax | grep rails | grep -v grep
19507 ?        Sl   0:41 ruby script/rails s

但当我尝试在网络浏览器中访问该网站后,它就消失了!奇怪吧?

user@server.example.com:~$ ps ax | grep rails | grep -v grep
user@server.example.com:~$ [no output; returned to prompt]

所以,我的问题是:我该怎么做?如何切断正在运行的 Rails 进程和 Capistrano 之间的通信,让 Capistrano 继续执行剩余的任务,然后在不停止 Rails 服务器的情况下将终端提示返回给我?任何帮助将不胜感激。

【问题讨论】:

  • 我现在怀疑它从来没有起作用,我只是认为它起作用了,因为该过程仍在显示。

标签: ruby-on-rails exception-handling capistrano


【解决方案1】:

我现在意识到这是一个 PEBCAC 错误。我的 Capistrano 脚本中的 Begin-Rescue-End 块没有捕获(拯救)我的 inbound Ctrl-C。它只是将它传递给正在运行的 Rails 服务器进程,该进程顺从地以 SystemExit 退出,然后将其传递回 Capistrano 脚本,然后捕获 outbound 异常。到那时,这是一笔交易。从 Capistrano 脚本的上下文中捕获和处理 outbound 异常的次数不会阻止 Rails 服务器停止。所以,我现在明白为什么它不起作用了。但我仍然很好奇是否有办法做我想做的事情。这意味着在 Capistrano 的某个地方捕获我的入站中断并在将其传递到服务器之前对其进行处理。

【讨论】:

    【解决方案2】:

    您可以在 Ruby 中使用 Signal.trap 来捕捉 Ctrl-C。 但我不确定如何使用 Capistrano 完成所需的操作 - 您想生成一个不会在 Capistrano 进程终止时终止的孙进程。

    【讨论】:

    • 这会在inbound 中断信号 到达相关进程之前捕获它吗?如果是这样,这可能正是我想要的。我会检查一下。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 2011-08-26
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    相关资源
    最近更新 更多