class Daemons::PidFile
3. in the preconfigured directory /var/run
(:system
option for :dir_mode
)
2. in a directory given by :dir
(:normal
option for :dir_mode
)
as a daemon) resides (:script
option for :dir_mode
)
1. in a directory relative to the directory where the script (the one that is supposed to run
Daemons is configurable to store the Pid-Files relative to three different locations:
=== Where are the Pid-Files stored?
Each file just contains one line with the pid as string (for example 6432
).
run at any time)
(Note that <number>
is omitted if only one instance of the script can
<scriptname>.rb<number>.pid
Pid-Files generated by Daemons have to following format:
=== How does a Pid-File look like?
to exit when you issue a stop
command.
to send them so called signals. Daemons uses the TERM
signal to tell the script
Daemons needs the pid of the scripts that are currently running in the background
programs to find out the pid of a running script.
(pid) that is stored in a well-defined location of the filesystem thus allowing other
A Pid-File is a file containing the process identification number
=== What is a Pid-File?
def self.existing(path)
def self.existing(path) new_instance = PidFile.allocate new_instance.instance_variable_set(:@path, path) def new_instance.filename @path end new_instance end
def self.find_files(dir, progname, delete = false)
def self.find_files(dir, progname, delete = false) files = Dir[File.join(dir, "#{progname}_num*.pid")] files = Dir[File.join(dir, "#{progname}.pid")] if files.size == 0 files.delete_if { |f| not (File.file?(f) and File.readable?(f)) } if delete files.delete_if do |f| pid = File.open(f) { |h| h.read }.to_i rsl = !Pid.running?(pid) if rsl puts "pid-file for killed process #{pid} found (#{f}), deleting." begin; File.unlink(f); rescue ::Exception; end end rsl end end files end
def cleanup
def cleanup File.delete(filename) if pid == Process.pid end
def exist?
def exist? File.exist? filename end
def filename
def filename File.join(@dir, "#{@progname}#{@number ? '_num' + @number.to_s : '' }.pid") end
def initialize(dir, progname, multiple = false)
def initialize(dir, progname, multiple = false) @dir = File.expand_path(dir) @progname = progname @multiple = multiple @number = nil @number = 0 if multiple if multiple while File.exist?(filename) && @number < 1024 @number += 1 end if @number >= 1024 fail RuntimeException('cannot run more than 1024 instances of the application') end end end
def pid
def pid begin File.open(filename) do |f| p = f.gets.to_i return nil if p == 0 # Otherwise an invalid pid file becomes pid 0 return p end rescue ::Exception return nil end end
def pid=(p)
def pid=(p) File.open(filename, 'w') do |f| f.chmod(0644) f.puts p # Process.pid end end
def zap
def zap File.delete(filename) end