Class: RFlow::PIDFile

Inherits:
Object
  • Object
show all
Defined in:
lib/rflow/pid_file.rb

Overview

Represents a file on disk that contains RFlow’s PID, for process management.

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ PIDFile

Returns a new instance of PIDFile.



8
9
10
# File 'lib/rflow/pid_file.rb', line 8

def initialize(path)
  @path = path
end

Instance Method Details

#readInteger

Read the pid file and get the PID from it.

Returns:

  • (Integer)


14
15
16
17
18
19
20
21
22
23
# 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?boolean

Determine if the application is running by checking the running PID and the pidfile.

Returns:

  • (boolean)


52
53
54
55
56
57
58
59
60
# File 'lib/rflow/pid_file.rb', line 52

def running?
  return false unless exist?
  pid = read
  return false unless pid
  Process.kill(0, pid)
  pid
rescue Errno::ESRCH, Errno::ENOENT
  nil
end

This method returns an undefined value.

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.



67
68
69
# File 'lib/rflow/pid_file.rb', line 67

def safe_unlink
  (current_process? and unlink) rescue nil
end

#signal(sig) ⇒ void

This method returns an undefined value.

Signal the process with the matching PID with a given signal.



73
74
75
# File 'lib/rflow/pid_file.rb', line 73

def signal(sig)
  Process.kill(sig, read)
end

#write(pid = $$) ⇒ Integer

Write a new PID out to the pid file.

Returns:

  • (Integer)

    the pid



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 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::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