module Invoker # rip off from borg # https://github.com/code-mancers/borg/blob/master/lib/borg/borg_daemon.rb class Daemon attr_reader :process_name def initialize @process_name = 'invoker' end def start if running? Invoker::Logger.puts "Invoker daemon is already running" exit(0) elsif dead? File.delete(pid_file) if File.exist?(pid_file) end Invoker::Logger.puts "Running Invoker daemon" daemonize end def stop kill_process end def pid_file File.join(Invoker.home, ".invoker", "#{process_name}.pid") end def pid File.read(pid_file).strip.to_i end def log_file File.join(Invoker.home, ".invoker", "#{process_name}.log") end def daemonize if fork sleep(2) exit(0) else Process.setsid File.open(pid_file, "w") do |file| file.write(Process.pid.to_s) end Invoker::Logger.puts "Invoker daemon log is available at #{log_file}" redirect_io(log_file) $0 = process_name end end def kill_process pgid = Process.getpgid(pid) Process.kill('-TERM', pgid) File.delete(pid_file) if File.exist?(pid_file) Invoker::Logger.puts "Stopped Invoker daemon" end def process_running? Process.kill(0, pid) true rescue Errno::ESRCH false end def status @status ||= check_process_status end def pidfile_exists? File.exist?(pid_file) end def running? status == 0 end # pidfile exists but process isn't running def dead? status == 1 end private def check_process_status if pidfile_exists? && process_running? 0 elsif pidfile_exists? # but not process_running 1 else 3 end end def redirect_io(logfile_name = nil) redirect_file_to_target($stdin) redirect_stdout(logfile_name) redirect_stderr end def redirect_stderr redirect_file_to_target($stderr, $stdout) $stderr.sync = true end def redirect_stdout(logfile_name) if logfile_name begin $stdout.reopen logfile_name, "a" $stdout.sync = true rescue StandardError redirect_file_to_target($stdout) end else redirect_file_to_target($stdout) end end def redirect_file_to_target(file, target = "/dev/null") begin file.reopen(target) rescue; end end end end