Example #1
0
 def _start_monitors(self):
     self.stdout_monitor = PipeMonitor(self._proc.stdout,
                                       self._stdout_handler)
     self.stdout_monitor.start()
     self.stderr_monitor = PipeMonitor(self._proc.stderr,
                                       self._stderr_handler)
     self.stderr_monitor.start()
Example #2
0
 def start(self):
     self._dbmon_proc = Popen(["dada_dbmonitor", "-k", self._key],
                              stdout=PIPE,
                              stderr=PIPE,
                              shell=False,
                              close_fds=True)
     self._mon_thread = PipeMonitor(self._dbmon_proc.stderr,
                                    self._stdout_parser)
     self._mon_thread.start()
Example #3
0
class DbMonitor(object):
    def __init__(self, key, callback=None):
        self._key = key
        self._callback = callback
        self._dbmon_proc = None
        self._mon_thread = None

    def _stdout_parser(self, line):
        line = line.strip()
        try:
            values = map(int, line.split())
            free, full, clear, written, read = values[5:]
            fraction = float(full) / (full + free)
            params = {
                "fraction-full": fraction,
                "written": written,
                "read": read
            }
            log.debug("{} params: {}".format(self._key, params))
            if self._callback:
                self._callback(params)
            return params
        except Exception as error:
            log.warning("Unable to parse line with error".format(str(error)))
            return None

    def start(self):
        self._dbmon_proc = Popen(["dada_dbmonitor", "-k", self._key],
                                 stdout=PIPE,
                                 stderr=PIPE,
                                 shell=False,
                                 close_fds=True)
        self._mon_thread = PipeMonitor(self._dbmon_proc.stderr,
                                       self._stdout_parser)
        self._mon_thread.start()

    def stop(self):
        self._dbmon_proc.kill()
        self._mon_thread.join()
Example #4
0
class ManagedProcess(object):
    def __init__(self, cmdlineargs, stdout_handler=None, stderr_handler=None):
        self._proc = Popen(map(str, cmdlineargs),
                           stdout=PIPE,
                           stderr=PIPE,
                           shell=False,
                           close_fds=True)
        if stdout_handler:
            self._stdout_handler = stdout_handler
        else:
            self._stdout_handler = lambda line: log.debug(line.strip())
        if stderr_handler:
            self._stderr_handler = stderr_handler
        else:
            self._stderr_handler = lambda line: log.warning(line.strip())
        self.stdout_monitor = None
        self.stderr_monitor = None
        self.eop_monitor = None
        self._start_monitors()

    @property
    def pid(self):
        return self._proc.pid

    def is_alive(self):
        return self._proc.poll() is None

    def _start_monitors(self):
        self.stdout_monitor = PipeMonitor(self._proc.stdout,
                                          self._stdout_handler)
        self.stdout_monitor.start()
        self.stderr_monitor = PipeMonitor(self._proc.stderr,
                                          self._stderr_handler)
        self.stderr_monitor.start()

    def _stop_monitors(self):
        self.stdout_monitor.join()
        self.stdout_monitor = None
        self.stderr_monitor.join()
        self.stderr_monitor = None

    def terminate(self, timeout=5):
        start = time.time()
        while self._proc.poll() is None:
            time.sleep(0.5)
            if (time.time() - start) > timeout:
                self._proc.kill()
        self._stop_monitors()
Example #5
0
class ManagedProcess(object):
    def __init__(self,
                 cmdlineargs,
                 env={},
                 umask=0o000,
                 stdout_handler=None,
                 stderr_handler=None):
        """
        @brief Manages a long running process and passes stdout and stderr to handlers.

        @param cmdlineargs  string or list of commandline arguments used to create the subprocess
        @param env   Dict of environemnet variables set for the process
        @param umask  Default permissions for files created byh this subprocess. Defaults to globally read and writeable!
        @param stdout_handler Handler for ouptut written to stdout
        @param stderr_handler Handler for ouptut written to stderr
        """
        # cmdlineargs to list of strings
        if isinstance(cmdlineargs, str) or isinstance(cmdlineargs, unicode):
            cmdlineargs = cmdlineargs.split()
        cmdlineargs = map(str, cmdlineargs)
        self._cmdl = " ".join(cmdlineargs)

        def preexec_fn():
            os.umask(umask)

        environ = os.environ.copy()
        environ.update(env)

        self._proc = Popen(cmdlineargs,
                           stdout=PIPE,
                           stderr=PIPE,
                           shell=False,
                           env=environ,
                           close_fds=True,
                           preexec_fn=preexec_fn)
        log.debug("Running command %s as pid %i", self._cmdl, self._proc.pid)
        if stdout_handler:
            self._stdout_handler = stdout_handler
        else:
            self._stdout_handler = lambda line: log.debug(self._cmdl + ":\n   "
                                                          + line.strip())
        if stderr_handler:
            self._stderr_handler = stderr_handler
        else:
            self._stderr_handler = lambda line: log.error(self._cmdl + ":\n   "
                                                          + line.strip())
        self.stdout_monitor = None
        self.stderr_monitor = None
        self.eop_monitor = None
        self._start_monitors()

    @property
    def pid(self):
        return self._proc.pid

    @property
    def returncode(self):
        return self._proc.returncode

    def is_alive(self):
        return self._proc.poll() is None

    def _start_monitors(self):
        self.stdout_monitor = PipeMonitor(self._proc.stdout,
                                          self._stdout_handler)
        self.stdout_monitor.start()
        self.stderr_monitor = PipeMonitor(self._proc.stderr,
                                          self._stderr_handler)
        self.stderr_monitor.start()

    def _stop_monitors(self):
        if self.stdout_monitor is not None:
            self.stdout_monitor.stop()
            self.stdout_monitor.join(3)
            self.stdout_monitor = None
        if self.stderr_monitor is not None:
            self.stderr_monitor.stop()
            self.stderr_monitor.join(3)
            self.stderr_monitor = None

    def terminate(self, timeout=5):
        start = time.time()
        self._stop_monitors()
        log.debug("Trying to terminate process {} ...".format(self._cmdl))
        if self._proc is None:
            log.warning(" process already terminated!".format())
            return

        while self._proc.poll() is None:
            time.sleep(0.5)
            if (time.time() - start) > timeout:
                log.debug("Reached timeout - Killing process")
                self._proc.kill()
                break
        self._proc = None  # delete to avoid zombie process
Example #6
0
class DbMonitor(object):
    """
    @brief Monitor a dada buffer using dada_dbmonitor
    """
    def __init__(self, key, callback=None):
        """
        @ brief Constructor

        @param key       key of dadabuffer to monitor
        @param callback  Function to pass monitor info to.

        @detail Callback receives dict containing parsed output of dada_dbmonitor
        """
        self._key = key
        self._dbmon_proc = None
        self._mon_thread = None
        self._callback = callback

        self.__parsed_lines = 0
        self.__headersize = 12  # Skip first 12 lines

    def _stdout_parser(self, line):
        """
        @brief Parse a line of output of the subprocess.
        """
        self.__parsed_lines += 1
        if self.__parsed_lines < self.__headersize:
            return None

        line = line.strip()

        try:
            values = map(int, line.split())
            free, full, clear, written, read = values[5:]
            fraction = float(full) / (full + free)
            params = {
                "key": self._key,
                "fraction-full": fraction,
                "written": written,
                "read": read
            }
        except Exception as error:
            log.warning("Unable to parse line {} with error".format(
                line, str(error)))
            return None
        if self._callback is not None:
            self._callback(params)

    def start(self):
        """
        @brief Start the monitor subprocess
        """
        self._dbmon_proc = Popen(["dada_dbmonitor", "-k", self._key],
                                 stdout=PIPE,
                                 stderr=PIPE,
                                 shell=False,
                                 close_fds=True)
        self._mon_thread = PipeMonitor(self._dbmon_proc.stderr,
                                       self._stdout_parser)
        self._mon_thread.start()

    def stop(self):
        """
        @brief Stop the monitor subprocess
        """
        log.debug("Stopping monitor thread for dada buffer: {}".format(
            self._key))
        self._dbmon_proc.terminate()
        self._mon_thread.stop()
        self._mon_thread.join(3)
        if self._dbmon_proc.returncode is None:
            log.warning(
                "Monitor thread for dada buffer: {} not terminated - killing it now!"
                .format(self._key))
            self._dbmon_proc.kill()
        self._dbmon_proc = None  # delete to avoid zombie process
Example #7
0
 def __init__(self, *args, **kwargs):
     PipeMonitor.__init__(self, *args, **kwargs)
     self.message_interval = 1.0
     self.last_message_time = 0.0