class PerfectQueue::Supervisor

Attributes

engine[R]

Public Class Methods

new(runner, config=nil, &block) click to toggle source
# File lib/perfectqueue/supervisor.rb, line 26
def initialize(runner, config=nil, &block)
  # initial logger
  STDERR.sync = true
  @log = DaemonsLogger.new(STDERR)

  @runner = runner
  block = Proc.new { config } if config
  @config_load_proc = block
end
run(runner, config=nil, &block) click to toggle source
# File lib/perfectqueue/supervisor.rb, line 22
def self.run(runner, config=nil, &block)
  new(runner, config, &block).run
end

Public Instance Methods

logrotated() click to toggle source
# File lib/perfectqueue/supervisor.rb, line 95
def logrotated
  @log.info "reopen a log file"
  @engine.logrotated
  @log.reopen!
  return true
end
replace(immediate, command=[$0]+ARGV) click to toggle source
# File lib/perfectqueue/supervisor.rb, line 83
def replace(immediate, command=[$0]+ARGV)
  @log.info immediate ? "Received immediate binary replace" : "Received graceful binary replace"
  begin
    @engine.replace(immediate, command)
  rescue
    @log.error "failed to replace: #{$!}"
    $!.backtrace.each {|bt| @log.warn "\t#{bt}" }
    return false
  end
  return true
end
restart(immediate) click to toggle source
# File lib/perfectqueue/supervisor.rb, line 71
def restart(immediate)
  @log.info immediate ? "Received immediate restart" : "Received graceful restart"
  begin
    @engine.restart(immediate, load_config)
  rescue
    @log.error "failed to restart: #{$!}"
    $!.backtrace.each {|bt| @log.warn "\t#{bt}" }
    return false
  end
  return true
end
run() click to toggle source
# File lib/perfectqueue/supervisor.rb, line 38
def run
  @log.info "PerfectQueue #{VERSION}"

  install_signal_handlers do
    config = load_config
    @engine = Engine.new(@runner, config)
    listen_debug_server(config)
    begin
      @engine.run
    ensure
      @engine.shutdown(true)
    end
  end

  return nil
rescue
  @log.error "#{$!.class}: #{$!}"
  $!.backtrace.each {|x| @log.warn "\t#{x}" }
  return nil
end
stop(immediate) click to toggle source
# File lib/perfectqueue/supervisor.rb, line 59
def stop(immediate)
  @log.info immediate ? "Received immediate stop" : "Received graceful stop"
  begin
    @engine.stop(immediate) if @engine
  rescue
    @log.error "failed to stop: #{$!}"
    $!.backtrace.each {|bt| @log.warn "\t#{bt}" }
    return false
  end
  return true
end

Private Instance Methods

install_signal_handlers(&block) click to toggle source
# File lib/perfectqueue/supervisor.rb, line 143
def install_signal_handlers(&block)
  s = self
  st = SignalThread.new do |st|
    st.trap :TERM do
      s.stop(false)
    end
    st.trap :INT do
      s.stop(false)
    end

    st.trap :QUIT do
      s.stop(true)
    end

    st.trap :USR1 do
      s.restart(false)
    end

    st.trap :HUP do
      s.restart(true)
    end

    st.trap :USR2 do
      s.logrotated
    end

    trap :CHLD, "SIG_IGN"
  end

  begin
    block.call
  ensure
    st.stop
  end
end
listen_debug_server(config) click to toggle source
# File lib/perfectqueue/supervisor.rb, line 118
def listen_debug_server(config)
  address = config[:debug].to_s
  return if address.empty?

  require 'drb'
  if address.include?('/')
    # unix
    require 'drb/unix'
    uri = "drbunix:#{address}"
    if File.exist?(address)
      File.unlink(address) rescue nil
    end
  else
    # tcp
    a, b = address.split(':',2)
    if b
      uri = "druby://#{a}:#{b}"
    else
      uri = "druby://0.0.0.0:#{a}"
    end
  end

  @debug_server = DRb::DRbServer.new(uri, self)
end
load_config() click to toggle source
# File lib/perfectqueue/supervisor.rb, line 103
def load_config
  raw_config = @config_load_proc.call
  config = {}
  raw_config.each_pair {|k,v| config[k.to_sym] = v }

  old_log = @log
  log = DaemonsLogger.new(config[:log] || STDERR)
  old_log.close if old_log
  @log = log

  config[:logger] = log

  return config
end