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
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
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