为什么Ruby服务器只在守护进程时产生僵尸?

时间:2014-03-19 10:51:15

标签: ruby fork daemon grape

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

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

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

机架配置(config.ru)

require './server.rb'

run Application::API

Grape服务器(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服务器。

1 个答案:

答案 0 :(得分:0)

删除

是否有帮助
r = Run.new 

位于support.rb

的底部

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