Add comments to Timer
[god.git] / lib / god / socket.rb
blob72914032ad9d1e37dd102de456ed2971d3255a55
1 require 'drb'
3 module God
5   # The God::Server oversees the DRb server which dishes out info on this God daemon.
6   class Socket
7     attr_reader :port
8     
9     # The location of the socket for a given port
10     #   +port+ is the port number
11     #
12     # Returns String (file location)
13     def self.socket_file(port)
14       "/tmp/god.#{port}.sock"
15     end
16     
17     # The address of the socket for a given port
18     #   +port+ is the port number
19     #
20     # Returns String (drb address)
21     def self.socket(port)
22       "drbunix://#{self.socket_file(port)}"
23     end
24     
25     # The location of the socket for this Server
26     #
27     # Returns String (file location)
28     def socket_file
29       self.class.socket_file(@port)
30     end
31     
32     # The address of the socket for this Server
33     #
34     # Returns String (drb address)
35     def socket
36       self.class.socket(@port)
37     end
38     
39     # Create a new Server and star the DRb server
40     #   +port+ is the port on which to start the DRb service (default nil)
41     def initialize(port = nil)
42       @port = port
43       start
44     end
45     
46     # Returns true
47     def ping
48       true
49     end
50     
51     # Forward API calls to God
52     #
53     # Returns whatever the forwarded call returns
54     def method_missing(*args, &block)
55       God.send(*args, &block)
56     end
57     
58     # Stop the DRb server and delete the socket file
59     #
60     # Returns nothing
61     def stop
62       DRb.stop_service
63       FileUtils.rm_f(self.socket_file)
64     end
65     
66     private
67     
68     # Start the DRb server. Abort if there is already a running god instance
69     # on the socket.
70     #
71     # Returns nothing
72     def start
73       begin
74         @drb ||= DRb.start_service(self.socket, self)
75         applog(nil, :info, "Started on #{DRb.uri}")
76       rescue Errno::EADDRINUSE
77         applog(nil, :info, "Socket already in use")
78         DRb.start_service
79         server = DRbObject.new(nil, self.socket)
80         
81         begin
82           Timeout.timeout(5) do
83             server.ping
84           end
85           abort "Socket #{self.socket} already in use by another instance of god"
86         rescue StandardError, Timeout::Error
87           applog(nil, :info, "Socket is stale, reopening")
88           File.delete(self.socket_file) rescue nil
89           @drb ||= DRb.start_service(self.socket, self)
90           applog(nil, :info, "Started on #{DRb.uri}")
91         end
92       end
93     end
94   end
96 end