class BufferedPopen(Popen): """ Open a process and Buffer the output to *any* IO object (like `io.BytesIO`) """ def __init__(self, args, stdout=None, iotimeout=None, timeout=None, **kwargs): self._output = stdout Popen.__init__(self, args, stdout=PIPE, stderr=STDOUT, **kwargs) self._iostream = IOStream(self.stdout, self._output, iotimeout, timeout, self.timeout_callback) self._iostream.start() def wait(self): """Wait for child process to terminate. Returns returncode attribute. If timeout is given, the process will be killed after timeout seconds if it is not finished """ returncode = Popen.wait(self) # self._finished_event.set() log.debug("returncode", returncode) if self._iostream.is_alive(): log.debug("self._io_thread.join()") self._iostream.join() return returncode def timeout_callback(self, reason='iotimeout'): log.debug("timeout_callback") if reason == 'iotimeout': self._output.write("\nTimeout: No output from program for %s seconds\n" % self._iostream.iotimeout) self._output.write("\nTimeout: If you require a longer timeout you " "may set the 'iotimeout' variable in your .binstar.yml file\n") self._output.write("[Terminating]\n") elif reason == 'timeout': self._output.write("\nTimeout: build exceeded maximum build time of %s seconds\n" % self._iostream.timeout) self._output.write("[Terminating]\n") else: self._output.write("\nTerminate: User requested build to be terminated\n") self._output.write("[Terminating]\n") self.kill_tree() def kill_tree(self): 'Kill all processes and child processes' try: log.warning("Kill Tree parent pid:%s" % self.pid) parent = psutil.Process(self.pid) except psutil.NoSuchProcess: log.warning("Parent pid %s is already dead" % self.pid) # Already dead return children = parent.children(recursive=True) self.kill() for child in children: if child.is_running(): log.warning(" - Kill child pid %s" % child.pid) child.kill()
class BufferedPopen(Popen): """ Open a process and Buffer the output to *any* IO object (like `io.BytesIO`) """ def __init__(self, args, stdout=None, iotimeout=None, timeout=None, **kwargs): self._output = stdout Popen.__init__(self, args, stdout=PIPE, stderr=STDOUT, **kwargs) self._iostream = IOStream(self.stdout, self._output, iotimeout, timeout, self.timeout_callback) self._iostream.start() def wait(self): """Wait for child process to terminate. Returns returncode attribute. If timeout is given, the process will be killed after timeout seconds if it is not finished """ # # if timeout: # self.kill_after(timeout) returncode = Popen.wait(self) # self._finished_event.set() log.debug("returncode", returncode) if self._iostream.is_alive(): log.debug("self._io_thread.join()") self._iostream.join() return returncode def timeout_callback(self, reason='iotimeout'): self.kill_tree() log.debug("timeout_callback") if reason == 'iotimeout': self._output.write( "\nTimeout: No output from program for %s seconds\n" % self._iostream.iotimeout) self._output.write( "\nTimeout: If you require a longer timeout you " "may set the 'iotimeout' variable in your .binstar.yml file\n") self._output.write("[Terminating]\n") elif reason == 'timeout': self._output.write( "\nTimeout: build exceeded maximum build time of %s seconds\n" % self._iostream.timeout) self._output.write("[Terminating]\n") else: self._output.write( "\nTerminate: User requested build to be terminated\n") self._output.write("[Terminating]\n") def kill_tree(self): 'Kill all processes and child processes' try: log.warn("Kill Tree parent pid:%s" % self.pid) parent = psutil.Process(self.pid) except psutil.NoSuchProcess: log.warn("Parent pid %s is already dead" % self.pid) # Already dead return children = parent.get_children(recursive=True) self.kill() for child in children: if child.is_running(): log.warn(" - Kill child pid %s" % child.pid) child.kill()