class MainLoop::Loop

Attributes

logger[R]

Public Class Methods

new(bus, dispatcher, logger: nil) click to toggle source
# File lib/main_loop/loop.rb, line 12
def initialize(bus, dispatcher, logger: nil)
  STDOUT.sync = true
  STDERR.sync = true
  @bus = bus
  @dispatcher = dispatcher
  @logger = logger || Logger.new(nil)
end

Public Instance Methods

crash(_command) click to toggle source
# File lib/main_loop/loop.rb, line 88
def crash(_command)
  @dispatcher.crash
end
install_signal_handlers(bus) click to toggle source

:nocov:

# File lib/main_loop/loop.rb, line 58
def install_signal_handlers(bus)
  TERM_SIGNALS.each do |sig|
    trap(sig) do |*_args|
      Thread.new(bus) {|b| b.puts "sig:#{sig}" }
    end
  end

  trap 'CLD' do
    Thread.new(bus) {|b| b.puts 'sig:CLD' }
  end
end
reap(command) click to toggle source
# File lib/main_loop/loop.rb, line 92
def reap(command)
  _, id, status = command.split(':')
  @dispatcher.reap_by_id(id, status)
end
reap_children() click to toggle source
# File lib/main_loop/loop.rb, line 97
def reap_children
  results = []

  @dispatcher.pids.each do |pid|
    if (result = self.wait2(pid))
      results << result
    end
  end

  Timeouter.loop(2) do
    unless (result = self.wait2(-1))
      break
    end

    results << result
  end

  results
rescue Errno::ECHILD
  results
end
run(timeout = 0) click to toggle source
# File lib/main_loop/loop.rb, line 20
def run(timeout = 0)
  install_signal_handlers(@bus)

  start_loop_forever(timeout)
rescue StandardError => e
  # :nocov:
  logger.fatal("Exception in Main Loop: #{e.inspect}")
  exit!(2)
  # :nocov:
end
signal(command) click to toggle source

:nocov:

# File lib/main_loop/loop.rb, line 71
def signal(command)
  _, sig = command.split(':')
  logger.debug("signal:#{sig}")

  if TERM_SIGNALS.include?(sig)
    @dispatcher.term
  elsif sig == 'CLD'
    # nothing to do child will reap later
  else
    logger.info("unhandled signal:#{sig}")
  end
end
start_loop_forever(timeout = 0) click to toggle source
# File lib/main_loop/loop.rb, line 31
def start_loop_forever(timeout = 0)
  wait = [[(timeout / 2.5), 5].min, 5].max
  Timeouter.loop(timeout) do
    event = @bus.gets(wait)
    logger.debug("command:#{event}")

    case event
    when 'term'
      term(event)
    when 'crash'
      crash(event)
    when /sig:/
      signal(event)
    when /reap:/
      reap(event)
    when nil
      logger.debug('Empty event: reaping...')
    else
      logger.debug("unknown event:#{event}")
    end

    @dispatcher.reap(reap_children) rescue nil
    @dispatcher.tick
  end
end
term(_command) click to toggle source
# File lib/main_loop/loop.rb, line 84
def term(_command)
  @dispatcher.term unless @dispatcher.terminating?
end
wait2(pid) click to toggle source

:nocov:

# File lib/main_loop/loop.rb, line 120
def wait2(pid)
  Process.wait2(pid, ::Process::WNOHANG)
end