父进程在一个单独的线程中启动一个EventMachine服务器,并在主线程中监视并重新生成死工作者。
子进程启动另一个EventMachine服务器,然后在五秒后退出。
问题是,当新子节点启动时,父进程的所有连接客户端都将断开连接。
我有什么办法可以做到这一点吗?
require 'eventmachine'
module EchoServer
def post_init
puts "-- someone connected to the echo server!"
end
def receive_data data
send_data ">>>you sent: #{data}"
close_connection if data =~ /quit/i
end
def unbind
puts "-- someone disconnected from the echo server!"
end
end
puts "Forking..."
def start_echo_server
Thread.new {
puts "Starting Echo server"
EventMachine.run {
EventMachine.start_server "127.0.0.1", 8081, EchoServer
}
}
end
def spawn_workers
if @pid = fork
@started = start_echo_server unless @started
else
puts "Child #{$$}: Sleeping for 5 seconds"
EventMachine.run {
EventMachine.start_server "127.0.0.1", 8082, EchoServer
EventMachine.add_timer(5) do
puts "Child #{$$}: exiting..."
exit
end
}
end
@pid
end
spawn_workers
if @pid
begin
# check if we have any child process that died
wpid, status = Process.waitpid2(-1, Process::WNOHANG)
wpid or (sleep 0.1 && next)
spawn_workers
rescue Errno::ECHILD
break
end while true
end
答案 0 :(得分:0)
问题:
Child复制父亲的记忆和代码。 (明显) 当您的父亲连接到某些客户端然后生成子项时,子项复制父项的EM循环及其所有“连接对象”。 当子进程启动新的EM循环时,从父进程复制的旧EM循环停止,因此所有连接对象都调用“close_connection”。你可能有问题为什么父亲连接对象复制在子关闭父亲和它的'客户端之间的连接?合理的问题。因为复制的对象仍然保持与父亲相同的套接字。
解决方案:
在您在孩子中调用EM.run之前,请在当前新生成的子项中从父派生的所有连接对象上调用“detach”。 “detach”会将子连接对象从套接字(父客户端)中分离出来,并阻止子进程关闭该套接字。