class DisqueJockey::Supervisor

Public Class Methods

logger() click to toggle source
# File lib/disque_jockey/supervisor.rb, line 12
def self.logger
  @logger ||= DisqueJockey::Logger.new('DisqueJockey')
end
work!() click to toggle source
# File lib/disque_jockey/supervisor.rb, line 4
def self.work!
  Process.daemon(true) if DisqueJockey.configuration.daemonize?
  load_workers
  spawn_worker_groups
  trap_signals_in_parent
  monitor_worker_groups
end
worker_classes() click to toggle source
# File lib/disque_jockey/supervisor.rb, line 16
def self.worker_classes
  @worker_classes ||= []
end

Private Class Methods

child_pids() click to toggle source
# File lib/disque_jockey/supervisor.rb, line 22
def self.child_pids
  @child_pids ||= []
end
load_workers() click to toggle source
# File lib/disque_jockey/supervisor.rb, line 30
def self.load_workers
  Dir.glob('**/workers/*.rb') {|f| require File.expand_path(f)}
end
monitor_worker_groups() click to toggle source
# File lib/disque_jockey/supervisor.rb, line 43
def self.monitor_worker_groups
  # this method never returns, it just
  # spawns new worker groups if their
  # processes exit.
  # DisqueJockey only exits if it receives a
  # kill signal
  loop do
    @dead_worker_groups.each do
      child_pid = @dead_disque_jockeys.shift
      logger.error "Child worker group exited: #{child_pid}"
      child_pids.delete(child_pid)
      spawn_worker_group
    end
    sleep(0.1)
  end
end
register_worker(worker_class) click to toggle source
# File lib/disque_jockey/supervisor.rb, line 26
def self.register_worker(worker_class)
  worker_classes.push(worker_class)
end
spawn_worker_group() click to toggle source
# File lib/disque_jockey/supervisor.rb, line 39
def self.spawn_worker_group
  child_pids << Process.fork { WorkerGroup.new(worker_classes).work! }
end
spawn_worker_groups() click to toggle source
# File lib/disque_jockey/supervisor.rb, line 34
def self.spawn_worker_groups
  raise NoWorkersFoundError, "No workers found! See README for instructions on loading workrers" if worker_classes.empty?
  DisqueJockey.configuration.worker_groups.times { spawn_worker_group }
end
trap_signals_in_parent() click to toggle source
# File lib/disque_jockey/supervisor.rb, line 60
def self.trap_signals_in_parent
  @dead_worker_groups = []
  %w(QUIT TERM INT ABRT CLD).each do |sig|
    trap(sig) do
      if sig == 'CLD'
        # if a child process dies, we want to
        # respawn another worker group
        # This needs to be reentrant, so we queue up dead child
        # processes to be handled in the run loop, rather than
        # acting here
        @dead_worker_groups << Process.wait
      else 
        begin
          child_pids.each { |pid| Process.kill(sig, pid) }
        ensure exit
        end
      end

    end
  end
end