Class: RunLoop::ProcessWaiter

Inherits:
Object
  • Object
show all
Includes:
Shell
Defined in:
lib/run_loop/process_waiter.rb

Overview

A class for waiting on processes.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Shell

run_shell_command, #run_shell_command

Methods included from Encoding

#transliterate

Constructor Details

#initialize(process_name, options = {}) ⇒ ProcessWaiter

Returns a new instance of ProcessWaiter


28
29
30
31
# File 'lib/run_loop/process_waiter.rb', line 28

def initialize(process_name, options={})
  @options = DEFAULT_OPTIONS.merge(options)
  @process_name = process_name
end

Instance Attribute Details

#process_nameObject (readonly)

Returns the value of attribute process_name


10
11
12
# File 'lib/run_loop/process_waiter.rb', line 10

def process_name
  @process_name
end

Class Method Details

.pgrep_f(match_string) ⇒ Object

Return a list of pids by matching `match_string` against the command and full argument list of the command. As the name suggests, this method uses `pgrep -f`.

Parameters:

  • match_string

    the string to match against


18
19
20
21
22
23
24
25
26
# File 'lib/run_loop/process_waiter.rb', line 18

def self.pgrep_f(match_string)
  cmd = ["pgrep", "-f", match_string]
  hash = RunLoop::Shell.run_shell_command(cmd)

  out = hash[:out]
  return [] if out.nil? || out == ""

  out.split($-0).map { |pid| pid.to_i }
end

Instance Method Details

#pidsArray<Integer>

Collect a list of Integer pids.

Returns:

  • (Array<Integer>)

    An array of integer pids for the `process_name`


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/run_loop/process_waiter.rb', line 35

def pids
  cmd = ["pgrep", "-x", process_name]
  hash = run_shell_command(cmd)
  out = hash[:out]

  if out.nil? || out == ""
    []
  else
    out.split($-0).map do |pid|
      if pid.nil? || pid == ""
        nil
      else
        pid.to_i
      end
    end.compact
  end
end

#running_process?Boolean

Is the `process_name` a running?

Returns:

  • (Boolean)

54
55
56
# File 'lib/run_loop/process_waiter.rb', line 54

def running_process?
  !pids.empty?
end

#wait_for_anyObject

Wait for `process_name` to start.


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/run_loop/process_waiter.rb', line 94

def wait_for_any
  return true if running_process?

  now = Time.now
  poll_until = now + @options[:timeout]
  delay = @options[:interval]
  is_alive = false
  while Time.now < poll_until
    is_alive = running_process?
    break if is_alive
    sleep delay
  end

  RunLoop.log_debug("Waited for #{Time.now - now} seconds for '#{process_name}' to start.")

  if @options[:raise_on_timeout] and !is_alive
    raise "Waited #{@options[:timeout]} seconds for '#{process_name}' to start."
  end
  is_alive
end

#wait_for_n(n) ⇒ Object

Wait for a number of process to start.

Parameters:

  • n (Integer)

    The number of processes to wait for.

Raises:

  • (ArgumentError)

    If n < 0

  • (ArgumentError)

    If n is not an Integer


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/run_loop/process_waiter.rb', line 62

def wait_for_n(n)
  unless n.is_a?(Integer)
    raise ArgumentError, "Expected #{n.class} to be #{1.class}"
  end

  unless n > 0
    raise ArgumentError, "Expected #{n} to be > 0"
  end

  return true if pids.count == n

  now = Time.now
  poll_until = now + @options[:timeout]
  delay = @options[:interval]
  there_are_n = false
  while Time.now < poll_until
    there_are_n = pids.count == n
    break if there_are_n
    sleep delay
  end

  plural = n > 1 ? "es" : ''
  RunLoop.log_debug("Waited for #{Time.now - now} seconds for #{n} '#{process_name}' process#{plural} to start.")

  if @options[:raise_on_timeout] and !there_are_n
    plural = n > 1 ? "es" : ''
    raise "Waited #{@options[:timeout]} seconds for #{n} '#{process_name}' process#{plural} to start."
  end
  there_are_n
end

#wait_for_noneObject

Wait for all `process_name` to finish.


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/run_loop/process_waiter.rb', line 116

def wait_for_none
  return true if !running_process?

  now = Time.now
  poll_until = now + @options[:timeout]
  delay = @options[:interval]
  has_terminated = false
  while Time.now < poll_until
    has_terminated = !self.running_process?
    break if has_terminated
    sleep delay
  end

  RunLoop.log_debug("Waited for #{Time.now - now} seconds for '#{process_name}' to die.")

  if @options[:raise_on_timeout] and !has_terminated
    raise "Waited #{@options[:timeout]} seconds for '#{process_name}' to die."
  end
  has_terminated
end