Process.detach 导致 sinatra-1.4.7 自动退出

Process.detach cause sinatra-1.4.7 auto exit

这是我的代码:

class App < Sinatra::Base
  get "/" do
    pid =fork do

    end
    Process.detach(pid)
  end
end
App.start!

当我curl localhost:4567时,服务器自动退出,输出为:

127.0.0.1 - - [13/Aug/2016:23:45:18 CST] "GET / HTTP/1.1" 200 0
- -> /
[2016-08-13 23:45:18] INFO  WEBrick::HTTPServer#start done.
== Sinatra has ended his set (crowd applauds)

我的环境是:

Linux Mint 17.3 Rosa
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]

为什么 Sinatra 在一个请求后就退出了?我想让它保持 运行 直到我故意杀死它。

不是 Process.detach 导致 Sinatra 退出,而是分叉进程结束并运行其 at_exit 挂钩的事实,它关闭了服务器(虽然我不太确定如何可以从子进程泄漏到父进程)。

有几种简单的方法可以防止这种情况发生。

  1. 我更喜欢这种一劳永逸的解决方案:

    configure do
      disable :traps
    end
    

    缺点是 Ctrl-C 会导致不那么优雅的退出。

  2. 或者,将此添加到任何 fork 块的开头:

    settings.running_server = nil
    

    缺点是您需要记住将此添加到所有分叉代码中。

您可能还会发现有人在所有 fork 块中建议 at_exit { Process.exit! },但我认为它不太可靠,因为其他 at_exit 处理程序可能会干扰它。

不幸的是,我在 Sinatra 中没有看到任何配置选项可以修复分叉并仍然允许优雅地处理 Ctrl-C。