class Shrimple::ProcessMonitor

Attributes

max_processes[RW]

Public Class Methods

new(max_processes=20) click to toggle source

pass 0 to disable max_processes

# File lib/shrimple/process_monitor.rb, line 13
def initialize(max_processes=20)
  @mutex ||= Mutex.new
  @processes ||= []   # TODO: convert this to a hash by child thread?
  @max_processes = max_processes
end

Public Instance Methods

_add(process) click to toggle source
# File lib/shrimple/process_monitor.rb, line 61
def _add process
  @mutex.synchronize do
    if @max_processes >= 0 && @processes.count >= @max_processes
      raise Shrimple::TooManyProcessesError.new("launched process #{@processes.count+1} of #{@max_processes} maximum")
    end
    @processes.push process
  end
end
_remove(process) { || ... } click to toggle source

removes process from process table. pass a block that cleans up after the process. _remove may be called lots of times but block will only be called once

# File lib/shrimple/process_monitor.rb, line 72
def _remove process
  cleanup = false

  @mutex.synchronize do
    cleanup = process._deactivate
    raise "process not in process table??" if cleanup && !@processes.include?(process)
  end

  # don't want to hold mutex when calling callback because it might block
  if cleanup
    yield
    @mutex.synchronize do
      value = @processes.delete(process)
      raise "someone else deleted process??" unless value
    end
  end
end
count() click to toggle source
# File lib/shrimple/process_monitor.rb, line 25
def count
  @mutex.synchronize do
    @processes.count
  end
end
find(&block) click to toggle source
# File lib/shrimple/process_monitor.rb, line 31
def find &block
  @mutex.synchronize do
    @processes.find(&block)
  end
end
first() click to toggle source
# File lib/shrimple/process_monitor.rb, line 19
def first
  @mutex.synchronize do
    @processes.first
  end
end
kill_all() click to toggle source
# File lib/shrimple/process_monitor.rb, line 37
def kill_all
  while f = first
    f.kill
  end
end
wait_next(nonblock=nil) click to toggle source

blocks until any child process returns (unless nonblock is true) raises an exception if no processes are running, or if called nonblocking and no processes have finished (see ThreadsWait#next_wait for details).

# File lib/shrimple/process_monitor.rb, line 46
def wait_next nonblock=nil
  # we wait on child threads since calling waitpid would produce a race condition.

  threads = {}
  @processes.each { |p|
    threads[p._child_thread] = p
  }

  thread = ThreadsWait.new(threads.keys).next_wait(nonblock)
  process = threads[thread]
  process.stop # otherwise process will be in an indeterminite state
  process
end