From 2a346f549503a233979acc829d058bbef0b800d3 Mon Sep 17 00:00:00 2001 From: Martin Styk Date: Mon, 28 Oct 2024 21:08:54 +0100 Subject: [PATCH] fix(concurrency): handle reading from pipe with Python 2 and 3 compatibility Signed-off-by: Martin Styk --- .../src/bkr/labcontroller/concurrency.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/LabController/src/bkr/labcontroller/concurrency.py b/LabController/src/bkr/labcontroller/concurrency.py index 9e48f9b1d..39b5e1515 100644 --- a/LabController/src/bkr/labcontroller/concurrency.py +++ b/LabController/src/bkr/labcontroller/concurrency.py @@ -16,6 +16,7 @@ import errno import logging import gevent.event, gevent.socket, gevent.hub +import six logger = logging.getLogger(__name__) @@ -29,22 +30,27 @@ def _read_from_pipe(f): discarding = False while True: try: + gevent.socket.wait_read(f.fileno()) chunk = f.read(4096) if not chunk: break if not discarding: chunks.append(chunk) if len(chunks) >= 1000: - logger.error('Too many chunks read from fd %s, ' - 'child process is running amok?!', f.fileno()) - chunks.append('+++ DISCARDED') + logger.error( + "Too many chunks read from fd %s, " + "child process is running amok?!", + f.fileno(), + ) + chunks.append(b"+++ DISCARDED") discarding = True except IOError as e: if e.errno != errno.EAGAIN: raise - sys.exc_clear() - gevent.socket.wait_read(f.fileno()) - return ''.join(chunks) + if six.PY3: + # Keep data in bytes until the end to reduce memory footprint + return b"".join(chunks).decode("utf-8") + return "".join(chunks) def _timeout_kill(p, timeout): gevent.sleep(timeout)