Class: Preforker::PidManager

Inherits:
Object
  • Object
show all
Defined in:
lib/preforker/pid_manager.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pid_path) ⇒ PidManager

Returns a new instance of PidManager.



5
6
7
# File 'lib/preforker/pid_manager.rb', line 5

def initialize(pid_path)
  set_pid_path(pid_path, $$)
end

Instance Attribute Details

#pidObject (readonly)

Returns the value of attribute pid.



3
4
5
# File 'lib/preforker/pid_manager.rb', line 3

def pid
  @pid
end

#pid_pathObject (readonly)

Returns the value of attribute pid_path.



3
4
5
# File 'lib/preforker/pid_manager.rb', line 3

def pid_path
  @pid_path
end

Instance Method Details

#set_pid_path(new_pid_path, new_pid) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/preforker/pid_manager.rb', line 9

def set_pid_path(new_pid_path, new_pid)
  if new_pid_path
    if read_pid = read_path_pid(new_pid_path)
      return new_pid_path if @pid_path && new_pid_path == @pid_path && read_pid == @pid
      raise ArgumentError, "#{$$} Already running on PID:#{read_pid} (or #{new_pid_path} is stale)"
    end
  end
  unlink_pid_safe(@pid_path) if @pid_path

  if new_pid_path
    fp = begin
           tmp = "#{File.dirname(new_pid_path)}/#{rand}.#{pid}"
           File.open(tmp, File::RDWR|File::CREAT|File::EXCL, 0644)
         rescue Errno::EEXIST
           retry
         end
    fp.syswrite("#{new_pid}\n")
    File.rename(fp.path, new_pid_path)
    fp.close
  end

  @pid = new_pid
  @pid_path = new_pid_path
end

unlinks a PID file at given path 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



38
39
40
41
# File 'lib/preforker/pid_manager.rb', line 38

def unlink
  File.unlink(@pid_path) if @pid_path && File.read(@pid_path).to_i == @pid
rescue
end