class Flatware::Sink::Signal

Constants

Message

Attributes

formatter[R]

Public Class Methods

listen(formatter, &block) click to toggle source
# File lib/flatware/sink/signal.rb, line 26
def self.listen(formatter, &block)
  new(formatter, &block).listen
end
new(formatter, &on_interrupt) click to toggle source
# File lib/flatware/sink/signal.rb, line 8
def initialize(formatter, &on_interrupt)
  @formatter = formatter
  Thread.main[:signals] = Queue.new

  @on_interrupt = on_interrupt
end

Public Instance Methods

listen() click to toggle source
# File lib/flatware/sink/signal.rb, line 15
def listen
  Thread.new(&method(:handle_signals))

  ::Signal.trap('INT') { signals << :int }
  ::Signal.trap('CLD') do
    signals << :cld if child_failed?
  end

  self
end

Private Instance Methods

child_failed?() click to toggle source
# File lib/flatware/sink/signal.rb, line 51
def child_failed?
  child_statuses.any? { |status| !status.success? }
end
child_status() click to toggle source
# File lib/flatware/sink/signal.rb, line 32
def child_status
  _worker_pid, status = begin
    Process.wait2(-1, Process::WNOHANG)
  rescue Errno::ECHILD
    []
  end
  status
end
child_statuses() click to toggle source
# File lib/flatware/sink/signal.rb, line 41
def child_statuses
  statuses = []
  loop do
    status = child_status
    return statuses unless status

    statuses << status
  end
end
handle_signals() click to toggle source
# File lib/flatware/sink/signal.rb, line 55
def handle_signals
  signal_message(signals.pop) do
    Process.waitall
    @on_interrupt.call
  end

  abort
end
signal_message(signal) { || ... } click to toggle source
# File lib/flatware/sink/signal.rb, line 64
      def signal_message(signal)
        formatter.message(Message.new(format(<<~MESSAGE, { cld: 'A worker died', int: 'Interrupted' }.fetch(signal))))

          %s!

          Waiting for workers to finish their current jobs...
        MESSAGE

        yield

        formatter.message(Message.new('done.'))
      end
signals() click to toggle source
# File lib/flatware/sink/signal.rb, line 77
def signals
  Thread.main[:signals]
end