3

tl;博士:rackup -p 1234<= 有效。rackup -p 1234 -D<= 创建僵尸。为什么?

我在一个单独的文件中运行具有支持功能的 Grape API 服务器。我的目标是在服务器启动时创建一个在支持函数中定义的长时间运行的单独后台进程,该进程会定期对数据库执行 ping 操作,并在找到具有某些标志的数据时执行一些操作。在服务器作为守护进程运行之前,这可以完美运行。当作为守护进程运行时,对服务器的每次调用都会创建一个僵尸进程。

为什么?我已经阅读了有关僵尸,分叉等的内容,但必须缺少一些关键概念...

机架配置 (config.ru)

require './server.rb'

run Application::API

葡萄服务器(server.rb)

require_relative 'support.rb'
module Application
  class API < Grape::API
    helpers do
      def current_runner
        @current_runner ||= Run.new
      end
      # ...
    end
    resource :tests do
      post :create do
        current_runner # <= Edit: forgot to copy this over 
        @current_runner.create
      end
      get :lookup do
        current_runner # <= Edit: forgot to copy this over 
        @current_runner.lookup
      end
      # ...
    end
  end
end

支持功能(support.rb)

class Run
  def initialize
    # ...   
    test_untested
  end
  # ... other non-forked functions including 'lookup' and 'create'
  def test_untested
    # Text file with process ID to protect from duplicate listeners
    pid = ""
    File.open("processid.txt", "r") do |f|
      f.each_line do |line|
        pid << line
      end
    end
    pid = pid.to_s.gsub(/[^0-9]/, "").to_i
    # If the process responds to kill signal 0
    # a listener is still alive, and we need to exit
    pid_active = nil
    unless pid < 100
      begin
        pid_active = true if ((Process.kill 0, pid) > 0)
      rescue Errno::ESRCH => e
        pid_active = false
      end
    end
    unless pid_active
      Process.fork do # Tried Process.daemon -- it never runs.
        Process.detach(Process.pid) # <= Also tried 'Process.setsid' instead ...
        # Application logic ...
      end
    end
  end
end
r = Run.new

编辑:仅供参考:我使用的是 2 核 32 位 CentOS 6.5 服务器。

4

1 回答 1

0

有帮助去除吗

r = Run.new 

在 support.rb 的底部

当您需要“support.rb”时,运行 server.rb 的进程将自动生成一个新进程,它将通过执行文件底部的行来运行 Run 类。

于 2014-10-08T14:44:57.007 回答