class RFlow::PIDFile
Represents a file on disk that contains RFlow's PID, for process management.
Attributes
path[R]
Public Class Methods
new(path)
click to toggle source
# File lib/rflow/pid_file.rb, line 8 def initialize(path) @path = path end
Public Instance Methods
read()
click to toggle source
Read the pid file and get the PID from it. @return [Integer]
# File lib/rflow/pid_file.rb, line 14 def read return nil unless File.exist? path contents = File.read(path) if contents.empty? RFlow.logger.warn "Ignoring empty PID file #{path}" nil else contents.to_i end end
running?()
click to toggle source
Determine if the application is running by checking the running PID and the pidfile. @return [boolean]
# File lib/rflow/pid_file.rb, line 56 def running? return false unless exist? pid = read return false unless pid Process.kill(0, pid) pid rescue Errno::ESRCH, Errno::ENOENT nil end
safe_unlink()
click to toggle source
Unlinks a PID file if it contains the current PID. Still potentially racy without locking the directory (which is non-portable and may interact badly with other programs), but the window for hitting the race condition is small. @return [void]
# File lib/rflow/pid_file.rb, line 71 def safe_unlink (current_process? and unlink) rescue nil end
signal(sig)
click to toggle source
Signal the process with the matching PID with a given signal. @return [void]
# File lib/rflow/pid_file.rb, line 77 def signal(sig) Process.kill(sig, read) end
to_s()
click to toggle source
@!visibility private
# File lib/rflow/pid_file.rb, line 82 def to_s File.expand_path(path) end
write(pid = $$)
click to toggle source
Write a new PID out to the pid file. @return [Integer] the pid
# File lib/rflow/pid_file.rb, line 27 def write(pid = $$) return unless validate? RFlow.logger.debug "Writing PID #{pid} to file '#{to_s}'" tmp_path = File.join(File.dirname(path), ".#{File.basename(path)}") if File.exist? tmp_path RFlow.logger.warn "Deleting stale temp PID file #{tmp_path}" File.delete(tmp_path) end pid_fp = begin File.open(tmp_path, File::RDWR|File::CREAT|File::EXCL, 0644) rescue Errno::ENOENT => e RFlow.logger.fatal "Error while writing temp PID file '#{tmp_path}'; containing directory may not exist?" RFlow.logger.fatal "Exception #{e.class}: #{e.message}" abort rescue Errno::EACCES => e RFlow.logger.fatal "Access error while writing temp PID file '#{tmp_path}'" RFlow.logger.fatal "Exception #{e.class}: #{e.message}" abort end pid_fp.syswrite("#{pid}\n") File.rename(pid_fp.path, path) pid_fp.close pid end
Private Instance Methods
current_process?()
click to toggle source
# File lib/rflow/pid_file.rb, line 103 def current_process? read == $$ end
exist?()
click to toggle source
# File lib/rflow/pid_file.rb, line 99 def exist? File.exist? path end
unlink()
click to toggle source
# File lib/rflow/pid_file.rb, line 107 def unlink File.unlink(path) end
validate?()
click to toggle source
# File lib/rflow/pid_file.rb, line 87 def validate? if current_process? return nil elsif running? raise ArgumentError, "Process #{read.to_s} referenced in stale PID file '#{to_s}' still exists; probably attempting to run duplicate RFlow instances" elsif exist? RFlow.logger.warn "Found stale PID #{read.to_s} in PID file '#{to_s}', removing" unlink end true end