tl;dr: rackup -p 1234
<= works. rackup -p 1234 -D
<= creates zombies. Why?
I'm running a Grape API server with supporting functions in a separate file. My aim is for the start of the server to create a long-running separate background process defined in the supporting functions that pings a database at an interval and performs some actions if data with certain flags are found. This works perfectly until the server is racked-up as a daemon. When racked-up as a daemon, each call to the server creates a zombie process.
Why? I've read what I can on zombies, forking, etc. but must be missing some key concept ...
Rack configuration (config.ru)
require './server.rb'
run Application::API
Grape server (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
Supporting functions (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
Edit: FYI: I'm on a 2-core 32-bit CentOS 6.5 server.