Class: Servolux::PidFile
- Inherits:
-
Object
- Object
- Servolux::PidFile
- Defined in:
- lib/servolux/pid_file.rb
Overview
Synopsis
The PidFile manages the lifecycle of a PID file.
Details
A PID file contains the process ID of a given program. This file can be used by the program to indicate that it started successfully. The file can be used programmatically to look up the process ID and send signals to the program. The file can be used to ensure two instances of the same program are not started at the same time.
The PidFile class supports creating and deleting PID files. Methods are
provided to check if the program associated with the PID is alive?. Signals
can be sent to the program using the kill method.
Examples
Here is a simple example creating a PID file in the "/var/run" directory.
pid_file = Servolux::PidFile.new(:name => "test", :path => "/var/run")
pid_file.filename #=> "/var/run/test.pid"
pid_file.write
From another process we can access this PID file and send a HUP signal to
the program.
pid_file = Servolux::PidFile.new(:name => "test", :path => "/var/run")
pid_file.kill("HUP") if pid_file.alive?
Constant Summary collapse
- DEFAULT_MODE =
0640
Instance Attribute Summary collapse
-
#logger ⇒ Object
logger for outputting messages.
-
#mode ⇒ Object
PID file permissions mode.
-
#name ⇒ Object
the process name.
-
#path ⇒ Object
the path to the PID file.
Instance Method Summary collapse
-
#alive? ⇒ Boolean
Returns
trueif the process is currently running. -
#delete ⇒ Object
Delete the PID file if it exists.
-
#delete! ⇒ Object
Forcibly delete the PID file if it exists.
-
#exist? ⇒ Boolean
Returns
trueif the PID file exists. -
#filename ⇒ Object
Returns the full name of the PID file including path and extension.
-
#initialize(opts = {}) {|_self| ... } ⇒ PidFile
constructor
Create a new PID file instance.
-
#kill(signal = 'INT') ⇒ Object
Send a signal the process identified by the PID file.
-
#pid ⇒ Object
Returns the numeric PID read from the file or
nilif the file does not exist. -
#write(pid = Process.pid) ⇒ Object
Writes the given
pidto the PID file.
Constructor Details
#initialize(opts = {}) {|_self| ... } ⇒ PidFile
Create a new PID file instance.
opts - The options Hash :name - the name of the program :path - path to the PID file location :mode - file permissions mode :logger - logger for outputting messages
46 47 48 49 50 51 52 53 |
# File 'lib/servolux/pid_file.rb', line 46 def initialize( opts = {} ) @name = opts.fetch(:name, $0) @path = opts.fetch(:path, ".") @mode = opts.fetch(:mode, DEFAULT_MODE) @logger = opts.fetch(:logger, Servolux::NullLogger()) yield self if block_given? end |
Instance Attribute Details
#logger ⇒ Object
logger for outputting messages
36 37 38 |
# File 'lib/servolux/pid_file.rb', line 36 def logger @logger end |
#mode ⇒ Object
PID file permissions mode
35 36 37 |
# File 'lib/servolux/pid_file.rb', line 35 def mode @mode end |
#name ⇒ Object
the process name
33 34 35 |
# File 'lib/servolux/pid_file.rb', line 33 def name @name end |
#path ⇒ Object
the path to the PID file
34 35 36 |
# File 'lib/servolux/pid_file.rb', line 34 def path @path end |
Instance Method Details
#alive? ⇒ Boolean
Returns true if the process is currently running. Returns false if this
is not the case. The status of the process is determined by sending signal 0
to the process.
122 123 124 125 126 127 128 129 130 |
# File 'lib/servolux/pid_file.rb', line 122 def alive? pid = self.pid return if pid.nil? Process.kill(0, pid) true rescue Errno::ESRCH, Errno::ENOENT false end |
#delete ⇒ Object
Delete the PID file if it exists. This method first checks that the current
process PID is the same as the PID stored in the file. If the PIDs do not
match, then this method returns nil without taking any action.
Returns the filename of the deleted file or nil if no action was taken.
Raises Errno::EACCESS if you do not have permission to delete the file.
82 83 84 85 86 87 88 |
# File 'lib/servolux/pid_file.rb', line 82 def delete return unless pid == Process.pid fn = filename logger.debug "Deleting pid file #{fn.inspect}" File.delete fn fn end |
#delete! ⇒ Object
Forcibly delete the PID file if it exists. This method does NOT check that the current process PID against the PID stored in the file.
Returns the filename of the deleted file or nil if no action was taken.
Raises Errno::EACCESS if you do not have permission to delete the file.
95 96 97 98 99 100 101 |
# File 'lib/servolux/pid_file.rb', line 95 def delete! return unless exist? fn = filename logger.debug "Deleting pid file #{fn.inspect}" File.delete fn fn end |
#exist? ⇒ Boolean
Returns true if the PID file exists. Returns false otherwise.
104 105 106 |
# File 'lib/servolux/pid_file.rb', line 104 def exist? File.exist? filename end |
#filename ⇒ Object
Returns the full name of the PID file including path and extension.
56 57 58 59 60 |
# File 'lib/servolux/pid_file.rb', line 56 def filename fn = name.to_s.downcase.tr(" ","_") + ".pid" fn = File.join(path, fn) unless path.nil? fn end |
#kill(signal = 'INT') ⇒ Object
Send a signal the process identified by the PID file. The default signal to send is 'INT' (2). The signal can be given either as a string or a signal number.
signal - The signal to send to the process (String or Integer)
Returns an Integer or nil if an error was encountered.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/servolux/pid_file.rb', line 139 def kill( signal = 'INT' ) pid = self.pid return if pid.nil? signal = Signal.list.invert[signal] if signal.is_a?(Integer) logger.info "Killing PID #{pid} with #{signal}" Process.kill(signal, pid) rescue Errno::EINVAL logger.error "Failed to kill PID #{pid} with #{signal}: " \ "'#{signal}' is an invalid or unsupported signal number." nil rescue Errno::EPERM logger.error "Failed to kill PID #{pid} with #{signal}: " \ "Insufficient permissions." nil rescue Errno::ESRCH logger.error "Failed to kill PID #{pid} with #{signal}: " \ "Process is deceased or zombie." nil rescue Errno::EACCES => err logger.error err. nil rescue Errno::ENOENT => err logger.error "Could not find a PID file at #{pid_file.inspect}. " \ "Most likely the process is no longer running." nil rescue Exception => err unless err.is_a?(SystemExit) logger.error "Failed to kill PID #{pid} with #{signal}: #{err.}" end nil end |
#pid ⇒ Object
Returns the numeric PID read from the file or nil if the file does not
exist. If you do not have permission to access the file nil is returned.
110 111 112 113 114 115 116 117 |
# File 'lib/servolux/pid_file.rb', line 110 def pid fn = filename Integer(File.read(fn).strip) if File.exist?(fn) rescue Errno::EACCES => err logger.error "You do not have access to the PID file at " \ "#{fn.inspect}: #{err.}" nil end |
#write(pid = Process.pid) ⇒ Object
Writes the given pid to the PID file. The pid defaults to the current
process ID.
pid - The process ID to write to the file
Returns the filename of PID file. Raises Errno::EACCESS if you do not have permission to write the file.
69 70 71 72 73 74 |
# File 'lib/servolux/pid_file.rb', line 69 def write( pid = Process.pid ) fn = filename logger.debug "Writing pid file #{fn.inspect}" File.open(fn, 'w', mode) { |fd| fd.write(pid.to_s) } fn end |