module Eye::Process::Monitor private def load_external_pid_file newpid = failsafe_load_pid if !newpid self.pid = nil info 'load_external_pid_file: pid_file not found' :no_pid_file elsif process_pid_running?(newpid) self.pid = newpid res = compare_identity if res == :fail warn "load_external_pid_file: process <#{self.pid}> from pid_file failed check_identity" :bad_identity else args = Eye::SystemResources.args(self.pid) info "load_external_pid_file: process <#{self.pid}> from pid_file found and running (identity: #{res}) (#{args})" :ok end else @last_loaded_pid = newpid self.pid = nil info "load_external_pid_file: pid_file found, but process <#{newpid}> not found" :not_running end end def check_alive return unless up? # check that process runned if process_really_running? check_pid_file else warn "check_alive: process <#{self.pid}> not found" notify :info, 'crashed!' clear_pid_file(true) if control_pid? switch :crashed, Eye::Reason.new(:crashed) end end def check_pid_file ppid = failsafe_load_pid return if ppid == self.pid msg = "check_alive: pid_file (#{self[:pid_file]}) changed by itself (<#{self.pid}> => <#{ppid}>)" if control_pid? msg += ", reverting to <#{self.pid}> (the pid_file is controlled by eye)" unless failsafe_save_pid msg += ', pid_file write failed! O_o' end else changed_ago_s = Time.now - pid_file_ctime if !ppid msg += ", reverting to <#{self.pid}> (the pid_file is empty)" unless failsafe_save_pid msg += ', pid_file write failed! O_o' end elsif (changed_ago_s > self[:auto_update_pidfile_grace]) && process_pid_running?(ppid) && (compare_identity(ppid) != :fail) msg += ", trusting this change, and now monitor <#{ppid}>" self.pid = ppid elsif changed_ago_s > self[:revert_fuckup_pidfile_grace] msg += " over #{self[:revert_fuckup_pidfile_grace]}s ago, reverting to <#{self.pid}>, because <#{ppid}> not alive" unless failsafe_save_pid msg += ', pid_file write failed! O_o' end else msg += ', ignoring self-managed pid change' end end warn msg end def check_identity if compare_identity == :fail notify :info, 'crashed by identity!' switch :crashed, Eye::Reason.new(:crashed_by_identity) clear_pid_file if self[:clear_pid] false else true end end def check_crash unless down? debug { 'check crashed: skipped, process is not in down' } return end if self[:keep_alive] warn 'check crashed: process is down' if self[:restore_in] schedule_in self[:restore_in].to_f, :restore, Eye::Reason.new(:crashed) else schedule :restore, Eye::Reason.new(:crashed) end else warn 'check crashed: process without keep_alive' schedule :unmonitor, Eye::Reason.new(:crashed) end end def restore start if down? end end