class RBMK::Server
Public Class Methods
new()
click to toggle source
# File lib/rbmk/server.rb, line 7 def initialize $master = true @arvg0 = File.basename Process.argv0 @workers = {} end
Protected Class Methods
host()
click to toggle source
# File lib/rbmk/server.rb, line 35 def self.host; '127.0.0.1' end
port()
click to toggle source
# File lib/rbmk/server.rb, line 36 def self.port; 8389 end
upstream()
click to toggle source
# File lib/rbmk/server.rb, line 38 def self.upstream require 'rbmk/upstream' RBMK::Upstream.new end
Public Instance Methods
start()
click to toggle source
# File lib/rbmk/server.rb, line 13 def start require 'rbmk/version' $log.info sprintf('rbmk version %s (codename %p) is warming up in an orange glow', VERSION, CODENAME) require 'socket' @upstream = self.class.upstream $log.debug sprintf('Listening on %s:%s', self.class.host, self.class.port) @socket = TCPServer.new self.class.host, self.class.port $0 = sprintf '%s master at %s:%s', @arvg0, self.class.host, self.class.port Signal.trap('CHLD') { raise SignalException, 'CHLD' } loop { accept } ensure @socket.close rescue nil $log.debug sprintf('Disposing of workers: %p', @workers.keys) Signal.trap('CHLD') {} # we'll bury them in synchronous fashion Thread.abort_on_exception = true @workers.each { |pid,_| Thread.new { kill pid } } sleep(0.1) while Thread.list.count > 1 # make sure everyone is dead $log.info 'Shutdown sequence complete' end
Protected Instance Methods
accept()
click to toggle source
# File lib/rbmk/server.rb, line 43 def accept peer = Peer.new @socket.accept $log.info 'Connection from %s' % peer if pid = fork then peer.close @workers[pid] = true else $log.debug 'Worker started' @socket.close act_as_a_child_for peer end rescue SignalException $log.debug 'Trapped %p' % ($!.signm.empty? ? 'SIGINT' : $!.signm) case $!.signo when SIGCHLD then reap when SIGINT, SIGHUP, SIGTERM then exit when SIGQUIT then $log.debug 'Committing emergency suicide' exit! else raise $! end end
act_as_a_child_for(peer)
click to toggle source
# File lib/rbmk/server.rb, line 66 def act_as_a_child_for peer Signal.trap 'CHLD', 'SYSTEM_DEFAULT' $master = false remove_instance_variable :@workers $0 = sprintf '%s worker for %s', @arvg0, peer serve peer rescue SignalException $log.debug 'Trapped %p' % ($!.signm.empty? ? 'SIGINT' : $!.signm) raise $! rescue Exception $!.log ensure $log.debug 'Terminating' exit! end
kill(pid)
click to toggle source
# File lib/rbmk/server.rb, line 87 def kill pid $log.debug 'Killing worker %s' % pid Process.kill 'TERM', pid Process.wait pid $log.debug 'Worker %s will not be a problem anymore' % pid rescue Errno::ESRCH $log.debug 'Somehow worker %s was not alive' % pid rescue Errno::ECHILD $log.debug 'Worker %s has suddenly disappeared' % pid end
reap()
click to toggle source
# File lib/rbmk/server.rb, line 98 def reap loop { pid, status = Process.wait2 -1, Process::WNOHANG raise Errno::ECHILD if pid.nil? @workers.delete pid $log.debug 'Reaped %s' % pid } rescue Errno::ECHILD end
serve(peer)
click to toggle source
# File lib/rbmk/server.rb, line 82 def serve peer require 'rbmk/worker' Worker.hire peer, @upstream end