diff --git a/.gitattributes b/.gitattributes index 8c45cec5081cc6da5bbb496a1cf6f6c22828a99d..5f5cb05926ee9fe7103fd992dbe964119dbb83cb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2683,6 +2683,7 @@ LCS/PyCommon/__init__.py -text LCS/PyCommon/datetimeutils.py -text LCS/PyCommon/factory.py -text LCS/PyCommon/postgres.py -text +LCS/PyCommon/subprocess.py -text LCS/PyCommon/test/python-coverage.sh eol=lf LCS/PyCommon/test/t_dbcredentials.run eol=lf LCS/PyCommon/test/t_dbcredentials.sh eol=lf diff --git a/LCS/PyCommon/CMakeLists.txt b/LCS/PyCommon/CMakeLists.txt index 7ab73b50fc58d930bd66d0c962c9d04298fb5250..a919cec71b6106e2dff3605edb7ec52380b7f975 100644 --- a/LCS/PyCommon/CMakeLists.txt +++ b/LCS/PyCommon/CMakeLists.txt @@ -12,7 +12,8 @@ set(_py_files methodtrigger.py util.py postgres.py - datetimeutils.py) + datetimeutils.py + subprocess.py) python_install(${_py_files} DESTINATION lofar/common) diff --git a/LCS/PyCommon/subprocess.py b/LCS/PyCommon/subprocess.py new file mode 100644 index 0000000000000000000000000000000000000000..cec18eeb8311581107b883570d4682251449ee39 --- /dev/null +++ b/LCS/PyCommon/subprocess.py @@ -0,0 +1,43 @@ +from threading import Thread +try: + from Queue import Queue, Empty +except ImportError: + from queue import Queue, Empty # python 3.x + +class PipeReader: + ''' + helper class to do non-blocking readline calls to a subprocess stdput or stderr pipe. + ''' + def __init__(self, pipe): + self.__line_buffer = '' + self.__queue = Queue() + self.__thread = Thread(target=PipeReader.enqueue_output, args=(pipe, self.__queue)) + self.__thread.daemon = True # thread dies with the program + self.__thread.start() + + @staticmethod + def enqueue_output(pipe, queue): + try: + for line in iter(pipe.readline, b''): + queue.put(line) + except Exception as e: + logger.error(e) + + def readline(self, timeout=None): + start = datetime.now() + while timeout==None or datetime.now() - start <= timedelta(seconds=timeout): + try: + result = self.__queue.get(True, timeout) + if result: + self.__line_buffer += result + except Empty: + pass + + endline_idx = self.__line_buffer.find('\n') + + if endline_idx > -1: + line = self.__line_buffer[:endline_idx] + self.__line_buffer = self.__line_buffer[endline_idx+1:] + return line + return '' +