From 43dd05810cd41cf545b5e6df67ad412793438043 Mon Sep 17 00:00:00 2001 From: Tom Werner Date: Fri, 26 Oct 2007 14:56:01 -0700 Subject: [PATCH] better handling of DRb unix domain socket --- History.txt | 1 + lib/god.rb | 7 +++++++ lib/god/process.rb | 3 +++ lib/god/socket.rb | 44 ++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/History.txt b/History.txt index ae4e98c..c1144fd 100644 --- a/History.txt +++ b/History.txt @@ -3,6 +3,7 @@ * Minor Enhancement * Move Syslog calls into God::Logger and clean up all calling code * Remove god's pid file on user requested termination + * Better handling and cleanup of DRb server's unix domain socket == 0.5.2 / 2007-10-10 diff --git a/lib/god.rb b/lib/god.rb index 8ba41a4..1ce43e0 100644 --- a/lib/god.rb +++ b/lib/god.rb @@ -362,8 +362,15 @@ module God return false end + # Force the termination of god. + # * Clean up pid file if one exists + # * Stop DRb service + # * Hard exit using exit! + # + # Never returns because the process will no longer exist! def self.terminate FileUtils.rm_f(self.pid) if self.pid + self.server.stop if self.server exit!(0) end diff --git a/lib/god/process.rb b/lib/god/process.rb index c74f020..a9c2c07 100644 --- a/lib/god/process.rb +++ b/lib/god/process.rb @@ -147,6 +147,9 @@ module God STDOUT.reopen self.log, "a" STDERR.reopen STDOUT + # close any other file descriptors + 3.upto(256){|fd| IO::new(fd).close rescue nil} + exec command unless command.empty? end end diff --git a/lib/god/socket.rb b/lib/god/socket.rb index 3874030..7291403 100644 --- a/lib/god/socket.rb +++ b/lib/god/socket.rb @@ -1,57 +1,93 @@ require 'drb' -# The God::Server oversees the DRb server which dishes out info on this God daemon. - module God + # The God::Server oversees the DRb server which dishes out info on this God daemon. class Socket attr_reader :port + # The location of the socket for a given port + # +port+ is the port number + # + # Returns String (file location) def self.socket_file(port) "/tmp/god.#{port}.sock" end + # The address of the socket for a given port + # +port+ is the port number + # + # Returns String (drb address) def self.socket(port) "drbunix://#{self.socket_file(port)}" end + # The location of the socket for this Server + # + # Returns String (file location) def socket_file self.class.socket_file(@port) end + # The address of the socket for this Server + # + # Returns String (drb address) def socket self.class.socket(@port) end + # Create a new Server and star the DRb server + # +port+ is the port on which to start the DRb service (default nil) def initialize(port = nil) @port = port start end + # Returns true def ping true end + # Forward API calls to God + # + # Returns whatever the forwarded call returns def method_missing(*args, &block) God.send(*args, &block) end + # Stop the DRb server and delete the socket file + # + # Returns nothing + def stop + DRb.stop_service + FileUtils.rm_f(self.socket_file) + end + private + # Start the DRb server. Abort if there is already a running god instance + # on the socket. + # + # Returns nothing def start begin @drb ||= DRb.start_service(self.socket, self) applog(nil, :info, "Started on #{DRb.uri}") rescue Errno::EADDRINUSE + applog(nil, :info, "Socket already in use") DRb.start_service server = DRbObject.new(nil, self.socket) begin - server.ping + Timeout.timeout(5) do + server.ping + end abort "Socket #{self.socket} already in use by another instance of god" - rescue + rescue StandardError, Timeout::Error + applog(nil, :info, "Socket is stale, reopening") File.delete(self.socket_file) rescue nil @drb ||= DRb.start_service(self.socket, self) + applog(nil, :info, "Started on #{DRb.uri}") end end end -- 2.11.4.GIT