def __init__(self, path, args=[], warnwords=[], env=None, chdir="."): GObject.GObject.__init__(self) self.path = path self.args = args self.warnwords = warnwords self.env = env or os.environ self.buffer = "" self.linePublisher = EmitPublisher(self, "line", 'SubProcess.linePublisher', EmitPublisher.SEND_LIST) self.linePublisher.start() self.defname = os.path.split(path)[1] self.defname = self.defname[:1].upper() + self.defname[1:].lower() t = time.time() self.defname = (self.defname, time.strftime("%H:%m:%%.3f", time.localtime(t)) % (t % 60)) log.debug(path, extra={"task": self.defname}) argv = [str(u) for u in [self.path] + self.args] log.debug("SubProcess.__init__: spawning...", extra={"task": self.defname}) self.pid, stdin, stdout, stderr = GObject.spawn_async( argv, working_directory=chdir, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=GObject.SPAWN_DO_NOT_REAP_CHILD | GObject.SPAWN_SEARCH_PATH) log.debug("SubProcess.__init__: _initChannel...", extra={"task": self.defname}) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = GObject.IO_IN | GObject.IO_HUP #|GObject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) log.debug("SubProcess.__init__: channelsClosed...", extra={"task": self.defname}) self.channelsClosed = False self.channelsClosedLock = threading.Lock() log.debug("SubProcess.__init__: child_watch_add...", extra={"task": self.defname}) GObject.child_watch_add(self.pid, self.__child_watch_callback) log.debug("SubProcess.__init__: subprocExitCode...", extra={"task": self.defname}) self.subprocExitCode = (None, None) self.subprocFinishedEvent = threading.Event() subprocesses.append(self) log.debug("SubProcess.__init__: finished", extra={"task": self.defname})
def __init__(self, path, args=[], warnwords=[], env=None): gobject.GObject.__init__(self) self.path = path self.args = args self.warnwords = warnwords self.env = env or os.environ self.buffer = "" self.linePublisher = EmitPublisher(self, "line", EmitPublisher.SEND_LIST) self.linePublisher.start() self.defname = os.path.split(path)[1] self.defname = self.defname[:1].upper() + self.defname[1:].lower() t = time.time() self.defname = (self.defname, time.strftime("%H:%m:%%.3f", time.localtime(t)) % (t % 60)) log.debug(path + "\n", self.defname) argv = [str(u) for u in [self.path] + self.args] self.pid, stdin, stdout, stderr = gobject.spawn_async( argv, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=gobject.SPAWN_DO_NOT_REAP_CHILD | gobject.SPAWN_SEARCH_PATH) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = gobject.IO_IN | gobject.IO_HUP #|gobject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) self.channelsClosed = False self.channelsClosedLock = threading.Lock() gobject.child_watch_add(self.pid, self.__child_watch_callback) self.subprocExitCode = (None, None) self.subprocFinishedEvent = threading.Event() self.subprocFinishedEvent.clear() subprocesses.append(self) pool.start(self._wait4exit)
def __init__(self, path, args=[], warnwords=[], env=None, chdir="."): GObject.GObject.__init__(self) self.path = path self.args = args self.warnwords = warnwords self.env = env or os.environ self.buffer = "" self.linePublisher = EmitPublisher(self, "line", 'SubProcess.linePublisher', EmitPublisher.SEND_LIST) self.linePublisher.start() self.defname = os.path.split(path)[1] self.defname = self.defname[:1].upper() + self.defname[1:].lower() t = time.time() self.defname = (self.defname, time.strftime("%H:%m:%%.3f",time.localtime(t)) % (t%60)) log.debug(path, extra={"task":self.defname}) argv = [str(u) for u in [self.path]+self.args] log.debug("SubProcess.__init__: spawning...", extra={"task":self.defname}) self.pid, stdin, stdout, stderr = GObject.spawn_async(argv, working_directory=chdir, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=GObject.SPAWN_DO_NOT_REAP_CHILD|GObject.SPAWN_SEARCH_PATH) log.debug("SubProcess.__init__: _initChannel...", extra={"task":self.defname}) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = GObject.IO_IN|GObject.IO_HUP#|GObject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) log.debug("SubProcess.__init__: channelsClosed...", extra={"task":self.defname}) self.channelsClosed = False self.channelsClosedLock = threading.Lock() log.debug("SubProcess.__init__: child_watch_add...", extra={"task":self.defname}) GObject.child_watch_add(self.pid, self.__child_watch_callback) log.debug("SubProcess.__init__: subprocExitCode...", extra={"task":self.defname}) self.subprocExitCode = (None, None) self.subprocFinishedEvent = threading.Event() subprocesses.append(self) log.debug("SubProcess.__init__: finished", extra={"task":self.defname})
def __init__(self, path, args=[], warnwords=[], env=None): gobject.GObject.__init__(self) self.path = path self.args = args self.warnwords = warnwords self.env = env or os.environ self.buffer = "" self.linePublisher = EmitPublisher(self, "line", EmitPublisher.SEND_LIST) self.linePublisher.start() self.defname = os.path.split(path)[1] self.defname = self.defname[:1].upper() + self.defname[1:].lower() t = time.time() self.defname = (self.defname, time.strftime("%H:%m:%%.3f",time.localtime(t)) % (t%60)) log.debug(path+"\n", self.defname) argv = [str(u) for u in [self.path]+self.args] self.pid, stdin, stdout, stderr = gobject.spawn_async(argv, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=gobject.SPAWN_DO_NOT_REAP_CHILD|gobject.SPAWN_SEARCH_PATH) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = gobject.IO_IN|gobject.IO_HUP#|gobject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) self.channelsClosed = False self.channelsClosedLock = threading.Lock() gobject.child_watch_add(self.pid, self.__child_watch_callback) self.subprocExitCode = (None, None) self.subprocFinishedEvent = threading.Event() self.subprocFinishedEvent.clear() subprocesses.append(self) pool.start(self._wait4exit)
class SubProcess (GObject.GObject): __gsignals__ = { "line": (GObject.SignalFlags.RUN_FIRST, None, (object,)), "died": (GObject.SignalFlags.RUN_FIRST, None, ()) } def __init__(self, path, args=[], warnwords=[], env=None, chdir="."): GObject.GObject.__init__(self) self.path = path self.args = args self.warnwords = warnwords self.env = env or os.environ self.buffer = "" self.linePublisher = EmitPublisher(self, "line", 'SubProcess.linePublisher', EmitPublisher.SEND_LIST) self.linePublisher.start() self.defname = os.path.split(path)[1] self.defname = self.defname[:1].upper() + self.defname[1:].lower() t = time.time() self.defname = (self.defname, time.strftime("%H:%m:%%.3f",time.localtime(t)) % (t%60)) log.debug(path, extra={"task":self.defname}) argv = [str(u) for u in [self.path]+self.args] log.debug("SubProcess.__init__: spawning...", extra={"task":self.defname}) self.pid, stdin, stdout, stderr = GObject.spawn_async(argv, working_directory=chdir, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=GObject.SPAWN_DO_NOT_REAP_CHILD|GObject.SPAWN_SEARCH_PATH) log.debug("SubProcess.__init__: _initChannel...", extra={"task":self.defname}) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = GObject.IO_IN|GObject.IO_HUP#|GObject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) log.debug("SubProcess.__init__: channelsClosed...", extra={"task":self.defname}) self.channelsClosed = False self.channelsClosedLock = threading.Lock() log.debug("SubProcess.__init__: child_watch_add...", extra={"task":self.defname}) GObject.child_watch_add(self.pid, self.__child_watch_callback) log.debug("SubProcess.__init__: subprocExitCode...", extra={"task":self.defname}) self.subprocExitCode = (None, None) self.subprocFinishedEvent = threading.Event() subprocesses.append(self) log.debug("SubProcess.__init__: finished", extra={"task":self.defname}) def _initChannel (self, filedesc, callbackflag, callback, isstderr): channel = GLib.IOChannel(filedesc) channel.set_encoding(None) if sys.platform != "win32": channel.set_flags(GObject.IO_FLAG_NONBLOCK) if callback: tag = channel.add_watch(callbackflag, callback, isstderr) self.__channelTags.append(tag) return channel def _closeChannels (self): self.channelsClosedLock.acquire() try: if self.channelsClosed == True: return self.channelsClosed = True finally: self.channelsClosedLock.release() for tag in self.__channelTags: GObject.source_remove(tag) for channel in (self.inChannel, self.outChannel, self.errChannel): try: channel.close() except GObject.GError as error: pass def __setup (self): os.nice(15) def __child_watch_callback (self, pid, code): log.debug("SubProcess.__child_watch_callback: %s" % repr(code), extra={"task":self.defname}) # Kill the engine on any signal but 'Resource temporarily unavailable' self.subprocExitCode = (code, os.strerror(code)) if code != errno.EWOULDBLOCK: if isinstance(code, str): log.error(code, extra={"task":self.defname}) else: log.error(os.strerror(code), extra={"task":self.defname}) self.emit("died") self.gentleKill() def __io_cb (self, channel, condition, isstderr): while True: try: # line = channel.next()#readline() line = channel.readline() except StopIteration: # fix for pygi #return False return True # Some engines send author names in different encodinds (f.e. spike) if line.startswith("id author") or not line: return True if isstderr: log.error(line, extra={"task":self.defname}) else: for word in self.warnwords: if word in line: log.warning(line, extra={"task":self.defname}) break else: log.debug(line.rstrip(), extra={"task":self.defname}) self.linePublisher.put(line) def write (self, data): if self.channelsClosed: log.warning("Chan closed for %r" % data, extra={"task":self.defname}) return if data.rstrip(): log.info(data, extra={"task":self.defname}) self.inChannel.write(data) if data.endswith("\n"): try: self.inChannel.flush() except GObject.GError as e: log.error(str(e)+". Last line wasn't sent.", extra={"task":self.defname}) def sendSignal (self, sign): try: if sys.platform != "win32": os.kill(self.pid, signal.SIGCONT) os.kill(self.pid, sign) except OSError as error: if error.errno == errno.ESRCH: #No such process pass else: raise OSError(error) def gentleKill (self, first=1, second=1): t = Thread(target=self.__gentleKill_inner, name=fident(self.__gentleKill_inner), args=(first, second)) t.daemon = True t.start() def __gentleKill_inner (self, first, second): self.resume() self._closeChannels() time.sleep(first) code, string = self.subprocExitCode if code == None: self.sigterm() time.sleep(second) code, string = self.subprocExitCode if code == None: self.sigkill() self.subprocFinishedEvent.set() return self.subprocExitCode[0] self.subprocFinishedEvent.set() return code self.subprocFinishedEvent.set() self.linePublisher._del() return code def pause (self): self.sendSignal(signal.SIGSTOP) def resume (self): if sys.platform != "win32": self.sendSignal(signal.SIGCONT) def sigkill (self): self.sendSignal(signal.SIGKILL) def sigterm (self): self.sendSignal(signal.SIGTERM) def sigint (self): self.sendSignal(signal.SIGINT)
class SubProcess (gobject.GObject): __gsignals__ = { "line": (gobject.SIGNAL_RUN_FIRST, None, (object,)), "died": (gobject.SIGNAL_RUN_FIRST, None, ()) } def __init__(self, path, args=[], warnwords=[], env=None): gobject.GObject.__init__(self) self.path = path self.args = args self.warnwords = warnwords self.env = env or os.environ self.buffer = "" self.linePublisher = EmitPublisher(self, "line", EmitPublisher.SEND_LIST) self.linePublisher.start() self.defname = os.path.split(path)[1] self.defname = self.defname[:1].upper() + self.defname[1:].lower() t = time.time() self.defname = (self.defname, time.strftime("%H:%m:%%.3f",time.localtime(t)) % (t%60)) log.debug(path+"\n", self.defname) argv = [str(u) for u in [self.path]+self.args] self.pid, stdin, stdout, stderr = gobject.spawn_async(argv, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=gobject.SPAWN_DO_NOT_REAP_CHILD|gobject.SPAWN_SEARCH_PATH) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = gobject.IO_IN|gobject.IO_HUP#|gobject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) self.channelsClosed = False self.channelsClosedLock = threading.Lock() gobject.child_watch_add(self.pid, self.__child_watch_callback) self.subprocExitCode = (None, None) self.subprocFinishedEvent = threading.Event() self.subprocFinishedEvent.clear() subprocesses.append(self) pool.start(self._wait4exit) def _initChannel (self, filedesc, callbackflag, callback, isstderr): channel = gobject.IOChannel(filedesc) if sys.platform != "win32": channel.set_flags(gobject.IO_FLAG_NONBLOCK) if callback: tag = channel.add_watch(callbackflag, callback, isstderr) self.__channelTags.append(tag) return channel def _closeChannels (self): self.channelsClosedLock.acquire() try: if self.channelsClosed == True: return self.channelsClosed = True finally: self.channelsClosedLock.release() for tag in self.__channelTags: gobject.source_remove(tag) for channel in (self.inChannel, self.outChannel, self.errChannel): try: channel.close() except gobject.GError, error: pass
class SubProcess(GObject.GObject): __gsignals__ = { "line": (GObject.SignalFlags.RUN_FIRST, None, (object, )), "died": (GObject.SignalFlags.RUN_FIRST, None, ()) } def __init__(self, path, args=[], warnwords=[], env=None, chdir="."): GObject.GObject.__init__(self) self.path = path self.args = args self.warnwords = warnwords self.env = env or os.environ self.buffer = "" self.linePublisher = EmitPublisher(self, "line", 'SubProcess.linePublisher', EmitPublisher.SEND_LIST) self.linePublisher.start() self.defname = os.path.split(path)[1] self.defname = self.defname[:1].upper() + self.defname[1:].lower() t = time.time() self.defname = (self.defname, time.strftime("%H:%m:%%.3f", time.localtime(t)) % (t % 60)) log.debug(path, extra={"task": self.defname}) argv = [str(u) for u in [self.path] + self.args] log.debug("SubProcess.__init__: spawning...", extra={"task": self.defname}) self.pid, stdin, stdout, stderr = GObject.spawn_async( argv, working_directory=chdir, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=GObject.SPAWN_DO_NOT_REAP_CHILD | GObject.SPAWN_SEARCH_PATH) log.debug("SubProcess.__init__: _initChannel...", extra={"task": self.defname}) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = GObject.IO_IN | GObject.IO_HUP #|GObject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) log.debug("SubProcess.__init__: channelsClosed...", extra={"task": self.defname}) self.channelsClosed = False self.channelsClosedLock = threading.Lock() log.debug("SubProcess.__init__: child_watch_add...", extra={"task": self.defname}) GObject.child_watch_add(self.pid, self.__child_watch_callback) log.debug("SubProcess.__init__: subprocExitCode...", extra={"task": self.defname}) self.subprocExitCode = (None, None) self.subprocFinishedEvent = threading.Event() subprocesses.append(self) log.debug("SubProcess.__init__: finished", extra={"task": self.defname}) def _initChannel(self, filedesc, callbackflag, callback, isstderr): channel = GLib.IOChannel(filedesc) if sys.platform != "win32": channel.set_flags(GObject.IO_FLAG_NONBLOCK) if callback: tag = channel.add_watch(callbackflag, callback, isstderr) self.__channelTags.append(tag) return channel def _closeChannels(self): self.channelsClosedLock.acquire() try: if self.channelsClosed == True: return self.channelsClosed = True finally: self.channelsClosedLock.release() for tag in self.__channelTags: GObject.source_remove(tag) for channel in (self.inChannel, self.outChannel, self.errChannel): try: channel.close() except GObject.GError as error: pass def __setup(self): os.nice(15) def __child_watch_callback(self, pid, code): log.debug("SubProcess.__child_watch_callback: %s" % repr(code), extra={"task": self.defname}) # Kill the engine on any signal but 'Resource temporarily unavailable' self.subprocExitCode = (code, os.strerror(code)) if code != errno.EWOULDBLOCK: if isinstance(code, str): log.error(code, extra={"task": self.defname}) else: log.error(os.strerror(code), extra={"task": self.defname}) self.emit("died") self.gentleKill() def __io_cb(self, channel, condition, isstderr): while True: try: line = channel.next() #readline() except StopIteration: # fix for pygi #return False return True if not line: return True if isstderr: log.error(line, extra={"task": self.defname}) else: for word in self.warnwords: if word in line: log.warning(line, extra={"task": self.defname}) break else: log.debug(line.rstrip(), extra={"task": self.defname}) self.linePublisher.put(line) def write(self, data): if self.channelsClosed: log.warning("Chan closed for %r" % data, extra={"task": self.defname}) return if data.rstrip(): log.info(data, extra={"task": self.defname}) self.inChannel.write(data) if data.endswith("\n"): try: self.inChannel.flush() except GObject.GError as e: log.error(str(e) + ". Last line wasn't sent.", extra={"task": self.defname}) def sendSignal(self, sign): try: if sys.platform != "win32": os.kill(self.pid, signal.SIGCONT) os.kill(self.pid, sign) except OSError as error: if error.errno == errno.ESRCH: #No such process pass else: raise OSError(error) def gentleKill(self, first=1, second=1): t = Thread(target=self.__gentleKill_inner, name=fident(self.__gentleKill_inner), args=(first, second)) t.daemon = True t.start() def __gentleKill_inner(self, first, second): self.resume() self._closeChannels() time.sleep(first) code, string = self.subprocExitCode if code == None: self.sigterm() time.sleep(second) code, string = self.subprocExitCode if code == None: self.sigkill() self.subprocFinishedEvent.set() return self.subprocExitCode[0] self.subprocFinishedEvent.set() return code self.subprocFinishedEvent.set() self.linePublisher._del() return code def pause(self): self.sendSignal(signal.SIGSTOP) def resume(self): if sys.platform != "win32": self.sendSignal(signal.SIGCONT) def sigkill(self): self.sendSignal(signal.SIGKILL) def sigterm(self): self.sendSignal(signal.SIGTERM) def sigint(self): self.sendSignal(signal.SIGINT)
class SubProcess(gobject.GObject): __gsignals__ = { "line": (gobject.SIGNAL_RUN_FIRST, None, (object, )), "died": (gobject.SIGNAL_RUN_FIRST, None, ()) } def __init__(self, path, args=[], warnwords=[], env=None): gobject.GObject.__init__(self) self.path = path self.args = args self.warnwords = warnwords self.env = env or os.environ self.buffer = "" self.linePublisher = EmitPublisher(self, "line", EmitPublisher.SEND_LIST) self.linePublisher.start() self.defname = os.path.split(path)[1] self.defname = self.defname[:1].upper() + self.defname[1:].lower() t = time.time() self.defname = (self.defname, time.strftime("%H:%m:%%.3f", time.localtime(t)) % (t % 60)) log.debug(path + "\n", self.defname) argv = [str(u) for u in [self.path] + self.args] self.pid, stdin, stdout, stderr = gobject.spawn_async( argv, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=gobject.SPAWN_DO_NOT_REAP_CHILD | gobject.SPAWN_SEARCH_PATH) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = gobject.IO_IN | gobject.IO_HUP #|gobject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) self.channelsClosed = False self.channelsClosedLock = threading.Lock() gobject.child_watch_add(self.pid, self.__child_watch_callback) self.subprocExitCode = (None, None) self.subprocFinishedEvent = threading.Event() self.subprocFinishedEvent.clear() subprocesses.append(self) pool.start(self._wait4exit) def _initChannel(self, filedesc, callbackflag, callback, isstderr): channel = gobject.IOChannel(filedesc) if sys.platform != "win32": channel.set_flags(gobject.IO_FLAG_NONBLOCK) if callback: tag = channel.add_watch(callbackflag, callback, isstderr) self.__channelTags.append(tag) return channel def _closeChannels(self): self.channelsClosedLock.acquire() try: if self.channelsClosed == True: return self.channelsClosed = True finally: self.channelsClosedLock.release() for tag in self.__channelTags: gobject.source_remove(tag) for channel in (self.inChannel, self.outChannel, self.errChannel): try: channel.close() except gobject.GError, error: pass