class Sponges::Handler

Attributes

notifier[R]
queue[R]
supervisor[R]

Public Class Methods

new(supervisor) click to toggle source
# File lib/sponges/handler.rb, line 8
def initialize(supervisor)
  @supervisor = supervisor
  @queue, @notifier = IO.pipe
  at_exit do
    for_supervisor do
      Sponges.logger.info "Supervisor exits."
    end
  end
end

Public Instance Methods

call() click to toggle source
# File lib/sponges/handler.rb, line 22
def call
  Thread.new do
    while signal = @queue.gets do
      if Sponges::SIGNALS.include?(signal = find_signal(signal.chomp))
        send "handler_#{signal.to_s.downcase}", signal
      end
    end
  end
end
push(signal) click to toggle source
# File lib/sponges/handler.rb, line 18
def push(signal)
  @notifier.puts(signal)
end

Private Instance Methods

find_signal(signal) click to toggle source
# File lib/sponges/handler.rb, line 40
def find_signal(signal)
  return signal.to_sym if signal =~ /\D/
  if signal = Signal.list.find {|k,v| v == signal.to_i }
    signal.first.to_sym
  end
end
for_supervisor() { || ... } click to toggle source
# File lib/sponges/handler.rb, line 36
def for_supervisor
  yield if Process.pid == store.supervisor_pid
end
fork_children() click to toggle source
# File lib/sponges/handler.rb, line 121
def fork_children
  name = children_name
  pid = Sponges::Worker.new(supervisor, name).call
  Sponges.logger.info "Supervisor create a child with #{pid} pid."
  store.add_children pid
end
handler_chld(signal) click to toggle source
# File lib/sponges/handler.rb, line 66
def handler_chld(signal)
  for_supervisor do
    return if stopping?
    store.children_pids.each do |pid|
      begin
        if dead = Process.waitpid(pid.to_i, Process::WNOHANG)
          store.delete_children dead
          Sponges.logger.warn "Child #{dead} died. Restarting a new one..."
          Sponges::Hook.on_chld
          fork_children
        end
      rescue Errno::ECHILD => e
        # Don't panic
      end
    end
  end
end
handler_hup(signal)
Alias for: handler_int
handler_int(signal) click to toggle source
# File lib/sponges/handler.rb, line 84
def handler_int(signal)
  for_supervisor do
    @stopping = true
    Sponges.logger.info "Supervisor received #{signal} signal."
    kill_them_all(signal) and shutdown
  end
end
handler_quit(signal)
Alias for: handler_int
handler_term(signal)
Alias for: handler_int
handler_ttin(signal) click to toggle source
# File lib/sponges/handler.rb, line 47
def handler_ttin(signal)
  for_supervisor do
    Sponges.logger.warn "Supervisor increment child's pool by one."
    fork_children
  end
end
handler_ttou(signal) click to toggle source
# File lib/sponges/handler.rb, line 54
def handler_ttou(signal)
  for_supervisor do
    Sponges.logger.warn "Supervisor decrement child's pool by one."
    if store.children_pids.first
      kill_one(store.children_pids.first, :HUP)
      store.delete_children(store.children_pids.first)
    else
      Sponges.logger.warn "No more child to kill."
    end
  end
end
kill_one(pid, signal) click to toggle source
# File lib/sponges/handler.rb, line 102
def kill_one(pid, signal)
  begin
    Process.kill signal, pid
    Process.waitpid pid
    Sponges.logger.info "Child #{pid} receive a #{signal} signal."
  rescue Errno::ESRCH, Errno::ECHILD, SignalException => e
    # Don't panic
  end
end
kill_them_all(signal) click to toggle source
# File lib/sponges/handler.rb, line 96
def kill_them_all(signal)
  store.children_pids.map do |pid|
    Thread.new { kill_one(pid.to_i, signal) }
  end.each &:join
end
shutdown() click to toggle source
# File lib/sponges/handler.rb, line 112
def shutdown
  Process.waitall
  Sponges.logger.info "Children shutdown complete. Exiting..."
  store.clear(name)
  exit
rescue Errno::ESRCH, Errno::ECHILD, SignalException => e
  # Don't panic
end
stopping?() click to toggle source
# File lib/sponges/handler.rb, line 128
def stopping?
  @stopping
end