class PerfectQueue::Worker

Public Class Methods

new(runner, config=nil, &block) click to toggle source
# File lib/perfectqueue/worker.rb, line 26
def initialize(runner, config=nil, &block)
  block = Proc.new { config } if config
  config = block.call

  @config = config
  @runner = runner

  @detach_wait = config[:detach_wait] || config['detach_wait'] || 10.0

  @sv = Supervisor.new(runner, &block)
  @detach = false
  @finish_flag = BlockingFlag.new
end
run(runner, config=nil, &block) click to toggle source
# File lib/perfectqueue/worker.rb, line 22
def self.run(runner, config=nil, &block)
  new(runner, config, &block).run
end

Public Instance Methods

detach() click to toggle source
# File lib/perfectqueue/worker.rb, line 87
def detach
  send_signal(:INT)
  @detach = true
  @finish_flag.set!
end
logrotated() click to toggle source
# File lib/perfectqueue/worker.rb, line 83
def logrotated
  send_signal(:USR2)
end
restart(immediate) click to toggle source
# File lib/perfectqueue/worker.rb, line 79
def restart(immediate)
  send_signal(immediate ? :HUP : :USR1)
end
run() click to toggle source
# File lib/perfectqueue/worker.rb, line 40
def run
  @pid = fork do
    $0 = "perfectqueue-supervisor:#{@runner}"
    @sv.run
    exit! 0
  end

  install_signal_handlers

  begin

    until @finish_flag.set?
      pid, status = Process.waitpid2(@pid, Process::WNOHANG)
      break if pid
      @finish_flag.wait(1)
    end

    return if pid

    if @detach
      wait_time = Time.now + @detach_wait
      while (w = wait_time - Time.now) > 0
        sleep [0.5, w].min
        pid, status = Process.waitpid2(@pid, Process::WNOHANG)
        break if pid
      end

    else
      # child process finished unexpectedly
    end

  rescue Errno::ECHILD
  end
end
stop(immediate) click to toggle source
# File lib/perfectqueue/worker.rb, line 75
def stop(immediate)
  send_signal(immediate ? :QUIT : :TERM)
end

Private Instance Methods

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

    # override
    st.trap :INT do
      s.detach
    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
  end
end
send_signal(sig) click to toggle source
# File lib/perfectqueue/worker.rb, line 94
def send_signal(sig)
  begin
    Process.kill(sig, @pid)
  rescue Errno::ESRCH, Errno::EPERM
  end
end