From a6fe0ae4fc36becc55eb97e41ed3849c93ab3da9 Mon Sep 17 00:00:00 2001 From: Lukasz Sojka Date: Thu, 31 Oct 2024 09:32:50 +0100 Subject: [PATCH] fix(libssh2-runner): fix slow stderr read when no stdout In case there's only stderr stream and no data on stdout, stderr stream processing waits for stdout processing timeout (0.5s by default). This causes long processing of many stderr lines as this delay happens for each line. Fix by verifying first if given stream has data and proceed to next if not. refs: https://github.com/scylladb/java-driver/issues/258 (cherry picked from commit a09dd1ecf657584e96e6c7003e1560cbb3443645) --- sdcm/remote/libssh2_client/__init__.py | 27 +++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/sdcm/remote/libssh2_client/__init__.py b/sdcm/remote/libssh2_client/__init__.py index 2778e9ea14..74de560386 100644 --- a/sdcm/remote/libssh2_client/__init__.py +++ b/sdcm/remote/libssh2_client/__init__.py @@ -440,25 +440,30 @@ def _process_output( # pylint: disable=too-many-arguments, too-many-branches if perf_counter() > end_time: reader.stop() return False - if stdout_stream is not None: + + data_processed = False + if stdout_stream is not None and reader.stdout.qsize(): try: stdout = reader.stdout.get(timeout=timeout_read_data_chunk) data = stdout.decode(encoding, errors='ignore') + '\n' stdout_stream.write(data) for watcher in watchers: watcher.submit_line(data) + data_processed = True + except Exception: # pylint: disable=broad-except # noqa: BLE001 + pass + if stderr_stream is not None and reader.stderr.qsize(): + try: + stderr = reader.stderr.get(timeout=timeout_read_data_chunk) + data = stderr.decode(encoding) + '\n' + stderr_stream.write(data) + for watcher in watchers: + watcher.submit_line(data) + data_processed = True except Exception: # pylint: disable=broad-except # noqa: BLE001 pass - if stderr_stream is not None: - if reader.stderr.qsize(): - try: - stderr = reader.stderr.get(timeout=timeout_read_data_chunk) - data = stderr.decode(encoding) + '\n' - stderr_stream.write(data) - for watcher in watchers: - watcher.submit_line(data) - except Exception: # pylint: disable=broad-except # noqa: BLE001 - pass + if not data_processed: # prevent unbounded loop in case no data on the streams + sleep(timeout_read_data_chunk or 0.5) return True @staticmethod