class CrapServer::Forker
Handle preforking task. Will spawn 1 process per core.
Public Class Methods
new(sockets)
click to toggle source
# File lib/crap_server/forker.rb, line 5 def initialize(sockets) @sockets = sockets end
Public Instance Methods
run(&block)
click to toggle source
Initialize
# File lib/crap_server/forker.rb, line 10 def run(&block) begin @block_proc = block @child_pids = [] processor_count.times do @child_pids << spawn_child end check_children # If someone kill us, we kill our children. Yes, is sad, but we must do it :'( rescue ::Exception # If any kind of error happens, we must kill our children @child_pids.each do |cpid| begin # We send Ctrl+C to the process Process.kill(:INT, cpid) # If the process in not running or because any reason we have no privileges to kill him # We just only don't care. In any case, we can do nothing rescue Errno::ESRCH end end @sockets.each do |socket| # Shuts down communication on all copies of the connection. socket.shutdown socket.close end end end
Protected Instance Methods
check_children()
click to toggle source
The main loop that check if any process is killed. If one of them get killed, we spawn another one.
# File lib/crap_server/forker.rb, line 53 def check_children # We take care of our children. If someone kill one, me made another one. # PS: Is a hard work :P loop do pid = Process.wait @child_pids.delete(pid) @child_pids << spawn_child end end
processor_count()
click to toggle source
Extracted from github.com/grosser/parallel/blob/master/lib/parallel.rb Number of processors seen by the OS and used for process scheduling.
-
AIX: /usr/sbin/pmcycles (AIX 5+), /usr/sbin/lsdev
-
BSD: /sbin/sysctl
-
Cygwin: /proc/cpuinfo
-
Darwin: /usr/bin/hwprefs, /usr/sbin/sysctl
-
HP-UX: /usr/sbin/ioscan
-
IRIX: /usr/sbin/sysconf
-
Linux: /proc/cpuinfo
-
Minix 3+: /proc/cpuinfo
-
Solaris: /usr/sbin/psrinfo
-
Tru64 UNIX: /usr/sbin/psrinfo
-
UnixWare: /usr/sbin/psrinfo
# File lib/crap_server/forker.rb, line 78 def processor_count @processor_count ||= begin os_name = RbConfig::CONFIG["target_os"] if os_name =~ /mingw|mswin/ require 'win32ole' result = WIN32OLE.connect("winmgmts://").ExecQuery( "select NumberOfLogicalProcessors from Win32_Processor") result.to_enum.collect(&:NumberOfLogicalProcessors).reduce(:+) elsif File.readable?("/proc/cpuinfo") IO.read("/proc/cpuinfo").scan(/^processor/).size elsif File.executable?("/usr/bin/hwprefs") IO.popen("/usr/bin/hwprefs thread_count").read.to_i elsif File.executable?("/usr/sbin/psrinfo") IO.popen("/usr/sbin/psrinfo").read.scan(/^.*on-*line/).size elsif File.executable?("/usr/sbin/ioscan") IO.popen("/usr/sbin/ioscan -kC processor") do |out| out.read.scan(/^.*processor/).size end elsif File.executable?("/usr/sbin/pmcycles") IO.popen("/usr/sbin/pmcycles -m").read.count("\n") elsif File.executable?("/usr/sbin/lsdev") IO.popen("/usr/sbin/lsdev -Cc processor -S 1").read.count("\n") elsif File.executable?("/usr/sbin/sysconf") and os_name =~ /irix/i IO.popen("/usr/sbin/sysconf NPROC_ONLN").read.to_i elsif File.executable?("/usr/sbin/sysctl") IO.popen("/usr/sbin/sysctl -n hw.ncpu").read.to_i elsif File.executable?("/sbin/sysctl") IO.popen("/sbin/sysctl -n hw.ncpu").read.to_i else $stderr.puts "Unknown platform: " + RbConfig::CONFIG["target_os"] $stderr.puts "Assuming 1 processor." 1 end end end
spawn_child()
click to toggle source
Spawn a new Thread Pool in each process
# File lib/crap_server/forker.rb, line 41 def spawn_child fork do begin CrapServer::Application.send(:per_process_block).call if not CrapServer::Application.send(:per_process_block).nil? pool = CrapServer::ThreadPool.new @sockets pool.run &@block_proc rescue Interrupt end end end