/lib/god/socket.rb
Ruby | 96 lines | 54 code | 14 blank | 28 comment | 0 complexity | 5b03f567d85215fea9735210c5e711c1 MD5 | raw file
- require 'drb'
- 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
- Timeout.timeout(5) do
- server.ping
- end
- abort "Socket #{self.socket} already in use by another instance of god"
- 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
- end
- end