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
76
77
78
79
80
81
82
83
84
85
# File 'lib/run_loop/process_terminator.rb', line 55

def kill_process
  return true unless process_alive?

  debug_logging = RunLoop::Environment.debug?
  begin
    if debug_logging
      puts "Sending '#{kill_signal}' to #{display_name} process '#{pid}'"
    end
    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
    if debug_logging
      puts "Process with pid '#{pid}' does not exist; nothing to do."
    end
    # Return early; there is no need to wait if the process does not exist.
    return true
  rescue Errno::EPERM
    if debug_logging
      puts "Cannot kill process '#{pid}' with '#{kill_signal}'; not a child of this process"
    end
  rescue SignalException => e
    raise e.message
  end

  if debug_logging
    puts "Waiting for #{display_name} '#{pid}' to terminate"
  end
  wait_for_process_to_terminate
end

#process_alive?Boolean

Is the process ‘pid` alive?

Returns:

  • (Boolean)

    Returns true if the process is still alive.



89
90
91
92
93
94
95
96
97
98
# File 'lib/run_loop/process_terminator.rb', line 89

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