def _kill_process(self, box_configuration, process_name):
     """ method is called to kill a running process """
     try:
         self.logger.info('kill: %s {' % process_name)
         pid = box_configuration.get_process_pid(process_name)
         if pid is not None and psutil.pid_exists(int(pid)):
             p = psutil.Process(pid)
             p.kill()
             p.wait()
             box_configuration.set_process_pid(process_name, None)
             helper.update_configuration(self.logger, box_configuration)
             ProcessContext.remove_pid_file(process_name)
     except Exception:
         self.logger.error('Exception on killing: %s' % process_name, exc_info=True)
     finally:
         self.logger.info('}')
 def _start_process(self, box_configuration, process_name):
     try:
         self.logger.info('start: %s {' % process_name)
         p = psutil.Popen([get_python(), PROJECT_ROOT + '/' + PROCESS_STARTER, process_name],
                            close_fds=True,
                            cwd=settings['process_cwd'],
                            stdin=PIPE,
                            stdout=PIPE,
                            stderr=STDOUT)
         box_configuration.set_process_pid(process_name, p.pid)
         self.logger.info('Started %s with pid = %r' % (process_name, p.pid))
     except Exception:
         box_configuration.set_process_pid(process_name, None)
         self.logger.error('Exception on starting: %s' % process_name, exc_info=True)
     finally:
         helper.update_configuration(self.logger, box_configuration)
         self.logger.info('}')
    def _poll_process(self, box_configuration, process_name):
        """ between killing a process and its actual termination lies poorly documented requirement -
            <purging process' io pipes and reading exit status>.
            this can be done either by os.wait() or process.wait() """
        try:
            pid = box_configuration.get_process_pid(process_name)
            p = psutil.Process(pid)

            returncode = p.wait(timeout=0.01)
            if returncode is None:
                # process is already terminated
                self.logger.info('Process %s is terminated' % process_name)
                return
            else:
                # process is terminated; possibly by OS
                box_configuration.set_process_pid(process_name, None)
                helper.update_configuration(self.logger, box_configuration)
                self.logger.info('Process %s got terminated. Cleaning up' % process_name)
        except TimeoutExpired:
            # process is alive and OK
            pass
        except Exception:
            self.logger.error('Exception on polling: %s' % process_name, exc_info=True)