Class: CarrotRpc::ServerRunner::Pid

Inherits:
Object
  • Object
show all
Defined in:
lib/carrot_rpc/server_runner/pid.rb

Overview

Pid and pid path for CarrotRpc::ServerRunner

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path:, logger:) ⇒ Pid

Returns a new instance of Pid.

Parameters:

  • path (Path, nil)

    path to pid path



67
68
69
70
71
72
73
74
# File 'lib/carrot_rpc/server_runner/pid.rb', line 67

def initialize(path:, logger:)
  unless path.nil?
    # daemonization will change CWD so expand relative paths now
    @path = File.expand_path(path)
  end

  @logger = logger
end

Instance Attribute Details

#loggerLogger (readonly)

Returns:



6
7
8
# File 'lib/carrot_rpc/server_runner/pid.rb', line 6

def logger
  @logger
end

#pathString (readonly)

Returns:

  • (String)


9
10
11
# File 'lib/carrot_rpc/server_runner/pid.rb', line 9

def path
  @path
end

Class Method Details

.number_error_check_status(non_zero_pid) ⇒ :dead, ...

The status of the given ‘non_zero_pid` number.

Parameters:

  • non_zero_pid (Integer)

    a non-zero pid

Returns:

  • (:dead)

    if ‘pid` cannot be contacted

  • (:not_owned)

    if interacting with ‘pid` raises a permission error

  • (:running)

    if ‘pid` is running



34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/carrot_rpc/server_runner/pid.rb', line 34

def self.number_error_check_status(non_zero_pid)
  # sending signal `0` just performs error checking
  Process.kill(0, non_zero_pid)
rescue Errno::ESRCH
  # Invalid pid
  :dead
rescue Errno::EPERM
  # no privilege to interact with process
  :not_owned
else
  :running
end

.number_status(pid) ⇒ :dead, ...

The status of the given ‘pid` number.

Parameters:

  • pid (Integer)

    a 0 or positive PID

Returns:

  • (:dead)

    if ‘pid` is `0`

  • (:dead)

    if ‘pid` cannot be contacted

  • (:not_owned)

    if interacting with ‘pid` raises a permission error

  • (:running)

    if ‘pid` is running



20
21
22
23
24
25
26
# File 'lib/carrot_rpc/server_runner/pid.rb', line 20

def self.number_status(pid)
  if pid == 0
    :dead
  else
    number_error_check_status(pid)
  end
end

.path_status(path) ⇒ :exited, ...

Status of the ‘pid` inside `path`.

Returns:

  • (:exited)

    if ‘path` does not exist, which indicates the server never ran or exited cleanly

  • (:not_owned)

    if ‘path` cannot be read

  • (:dead)

    if ‘pid` is `0`

  • (:dead)

    if ‘pid` cannot be contacted

  • (:not_owned)

    if interacting with ‘pid` raises a permission error

  • (:running)

    if ‘pid` is running



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/carrot_rpc/server_runner/pid.rb', line 52

def self.path_status(path)
  pid = File.read(path).to_i
rescue Errno::ENOENT
  # File does not exist
  :exited
rescue Errno::EPERM
  # File cannot be read
  :not_owned
else
  number_status(pid)
end

Instance Method Details

#checkvoid

This method returns an undefined value.

Exits if status indicates server is already running, otherwise deletes #path.



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/carrot_rpc/server_runner/pid.rb', line 81

def check
  if path?
    case self.class.path_status(path)
    when :running, :not_owned
      logger.warn "A server is already running. Check #{path}"
      exit(1)
    when :dead
      delete
    end
  end
end

#deletevoid

This method returns an undefined value.

Deletes ‘path` if it is set



96
97
98
99
100
# File 'lib/carrot_rpc/server_runner/pid.rb', line 96

def delete
  if path? && File.exist?(path)
    File.delete(path)
  end
end

#delete_at_exitvoid

This method returns an undefined value.

Registers an ‘at_exit` handler to #delete.



105
106
107
108
109
# File 'lib/carrot_rpc/server_runner/pid.rb', line 105

def delete_at_exit
  at_exit do
    delete
  end
end

#ensure_writtenObject

Keeps trying to write #path until it succeeds



112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/carrot_rpc/server_runner/pid.rb', line 112

def ensure_written
  if path?
    begin
      write
    rescue Errno::EEXIST
      check

      retry
    else
      delete_at_exit
    end
  end
end

#path?true, false

Whether #path is set.

Returns:

  • (true)

    if #path is not ‘nil`.

  • (false)

    otherwise



130
131
132
# File 'lib/carrot_rpc/server_runner/pid.rb', line 130

def path?
  !path.nil?
end

#writevoid

This method returns an undefined value.

Write to process id path



137
138
139
140
141
# File 'lib/carrot_rpc/server_runner/pid.rb', line 137

def write
  File.open(path, File::CREAT | File::EXCL | File::WRONLY) do |f|
    f.write(Process.pid.to_s)
  end
end