module Fluent::DetachProcessImpl
def detach_process_impl(num, &block)
def detach_process_impl(num, &block) children = [] num.times do |i| pid, forward_thread = DetachProcessManager.instance.fork(self) if pid # parent process $log.info "detached process", :class=>self.class, :pid=>pid children << [pid, forward_thread] next end # child process begin on_detach_process(i) block.call # disable Engine.stop called by signal handler Engine.define_singleton_method(:stop) do # do nothing end # override signal handlers called by parent process fin = FinishWait.new trap :INT do fin.stop end trap :TERM do fin.stop end #forward_thread.join # TODO this thread won't stop because parent doesn't close pipe fin.wait exit! 0 ensure $log.error "unknown error while shutting down this child process", :error=>$!.to_s, :pid=>Process.pid $log.error_backtrace end exit! 1 end # parent process # override shutdown method to kill child processes define_singleton_method(:shutdown) do children.each {|pair| begin pid = pair[0] forward_thread = pair[1] if pid Process.kill(:TERM, pid) forward_thread.join # wait until child closes pipe Process.waitpid(pid) pair[0] = nil end rescue $log.error "unknown error while shutting down remote child process", :error=>$!.to_s $log.error_backtrace end } end # override target.emit and write event stream to the pipe forwarders = children.map {|pair| pair[1].forwarder } if forwarders.length > 1 # use roundrobin fwd = DetachProcessManager::MultiForwarder.new(forwarders) else fwd = forwarders[0] end define_singleton_method(:emit) do |tag,es,chain| chain.next fwd.emit(tag, es) end end
def on_detach_process(i)
def on_detach_process(i) end