Class: RunLoop::ProcessTerminator

Inherits:
Object
  • Object
show all
Defined in:
lib/run_loop/process_terminator.rb

Overview

A class for terminating processes and waiting for them to die.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pid, kill_signal, display_name, options = {}) ⇒ ProcessTerminator

Create a new process terminator.

@param pid The process pid. @param[String, Integer] kill_signal The kill signal to send to the process. @param display_name The name of the process to kill. Used only

in log messages and exceptions.

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :timeout (Float) — default: 2.0

    How long to wait for the process to terminate.

  • :interval (Float) — default: 0.1

    The polling interval.

  • :raise_on_no_terminate (Boolean) — default: false

    Should an error be raised if process does not terminate.


39
40
41
42
43
44
# File 'lib/run_loop/process_terminator.rb', line 39

def initialize(pid, kill_signal, display_name, options={})
  @options = DEFAULT_OPTIONS.merge(options)
  @pid = pid.to_i
  @kill_signal = kill_signal
  @display_name = display_name
end

Instance Attribute Details

#display_nameString (readonly)

The process name to use log messages and exceptions. Not used to find

or otherwise interact with the process.

Returns:

  • (String)

    The display name.


21
22
23
# File 'lib/run_loop/process_terminator.rb', line 21

def display_name
  @display_name
end

#kill_signalInteger, String (readonly)

The kill signal to send to the process. Can be a Unix signal name or an

Integer.

Returns:

  • (Integer, String)

    The kill signal.


15
16
17
# File 'lib/run_loop/process_terminator.rb', line 15

def kill_signal
  @kill_signal
end

#optionsHash (readonly)

Options to control the behavior of `kill_process`.

Returns:

  • (Hash)

    A hash of options.


26
27
28
# File 'lib/run_loop/process_terminator.rb', line 26

def options
  @options
end

#pidInteger (readonly)

The process id of the process.

Returns:

  • (Integer)

    The pid.


9
10
11
# File 'lib/run_loop/process_terminator.rb', line 9

def pid
  @pid
end

Instance Method Details

#kill_processBoolean

Try to kill the process identified by `pid`.

After sending `kill_signal` to `pid`, wait for the process to terminate.

Returns:

  • (Boolean)

    Returns true if the process was terminated or is no longer alive.

Raises:

  • (SignalException)

    Raised on an unhandled `Process.kill` exception. Errno:ESRCH and Errno:EPERM are handled exceptions; all others will be raised.


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/run_loop/process_terminator.rb', line 55

def kill_process
  return true unless process_alive?

  begin
    RunLoop.log_debug("Sending '#{kill_signal}' to #{display_name} process '#{pid}'")
    Process.kill(kill_signal, pid.to_i)
    # Don't wait.
    # We might not own this process and a WNOHANG would be a nop.
    # Process.wait(pid, Process::WNOHANG)
  rescue Errno::ESRCH
    RunLoop.log_debug("Process with pid '#{pid}' does not exist; nothing to do.")
    # Return early; there is no need to wait if the process does not exist.
    return true
  rescue Errno::EPERM
    RunLoop.log_debug("Cannot kill process '#{pid}' with '#{kill_signal}'; not a child of this process")
  rescue SignalException => e
    raise e.message
  end
  RunLoop.log_debug("Waiting for #{display_name} with pid '#{pid}' to terminate")
  wait_for_process_to_terminate
end

#process_alive?Boolean

Is the process `pid` alive?

Returns:

  • (Boolean)

    Returns true if the process is still alive.


79
80
81
82
83
84
85
86
87
88
# File 'lib/run_loop/process_terminator.rb', line 79

def process_alive?
  begin
    Process.kill(0, pid.to_i)
    true
  rescue Errno::ESRCH
    false
  rescue Errno::EPERM
    true
  end
end