From 82ba0a8dfb33d582fa83af79311d9e1ae437c334 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Wed, 24 Apr 2019 11:30:11 -0500 Subject: [PATCH 1/2] ProcessLogger: avoid spawning threads in noninteractive environments (https://github.com/firedrakeproject/firedrake/issues/1422) --- pytools/__init__.py | 36 +++++++++++++++++++++++++++++++++++- test/test_pytools.py | 16 +++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/pytools/__init__.py b/pytools/__init__.py index 9783522..6e23c57 100644 --- a/pytools/__init__.py +++ b/pytools/__init__.py @@ -2170,9 +2170,43 @@ class ProcessLogger(object): # pylint: disable=too-many-instance-attributes import threading self.late_start_log_thread = threading.Thread(target=self._log_start_if_long) + # Do not delay interpreter exit if thread not finished. self.late_start_log_thread.daemon = True - self.late_start_log_thread.start() + + # https://github.com/firedrakeproject/firedrake/issues/1422 + # Starting a thread may irrecoverably break various environments, + # e.g. MPI. + # + # Since the late-start logging is an optional 'quality-of-life' + # feature for interactive use, do not do it unless there is (weak) + # evidence of interactive use. + import sys + use_late_start_logging = sys.stdin.isatty() + + import os + if os.environ.get("PYTOOLS_LOG_NO_THREADS", ""): + use_late_start_logging = False + + if use_late_start_logging: + # https://github.com/firedrakeproject/firedrake/issues/1422 + # Starting a thread may irrecoverably break various environments, + # e.g. MPI. + # + # Since the late-start logging is an optional 'quality-of-life' + # feature for interactive use, do not do it unless there is (weak) + # evidence of interactive use. + + try: + self.late_start_log_thread.start() + except RuntimeError: + # https://github.com/firedrakeproject/firedrake/issues/1422 + # + # Starting a thread may fail in various environments, e.g. MPI. + # Since the late-start logging is an optional 'quality-of-life' + # feature for interactive use, tolerate failures of it without + # warning. + pass self.timer = ProcessTimer() diff --git a/test/test_pytools.py b/test/test_pytools.py index 91748c8..775b68b 100644 --- a/test/test_pytools.py +++ b/test/test_pytools.py @@ -1,9 +1,11 @@ from __future__ import absolute_import, division, with_statement import sys - import pytest +import logging +logger = logging.getLogger(__name__) + @pytest.mark.skipif("sys.version_info < (2, 5)") def test_memoize_method_clear(): @@ -185,6 +187,18 @@ def test_reshaped_view(): pytools.reshaped_view(b, -1) +def test_processlogger(): + logging.basicConfig(level=logging.INFO) + + from pytools import ProcessLogger + plog = ProcessLogger(logger, "testing the process logger", + long_threshold_seconds=0.01) + + from time import sleep + with plog: + sleep(0.3) + + if __name__ == "__main__": if len(sys.argv) > 1: exec(sys.argv[1]) -- GitLab From 4894677f5e66dbcef1ee47f1d807585ad02067e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Kl=C3=B6ckner?= Date: Thu, 25 Apr 2019 02:16:03 +0200 Subject: [PATCH 2/2] ProcessLogger: remove redundant comment --- pytools/__init__.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pytools/__init__.py b/pytools/__init__.py index 6e23c57..ded899c 100644 --- a/pytools/__init__.py +++ b/pytools/__init__.py @@ -2189,14 +2189,6 @@ class ProcessLogger(object): # pylint: disable=too-many-instance-attributes use_late_start_logging = False if use_late_start_logging: - # https://github.com/firedrakeproject/firedrake/issues/1422 - # Starting a thread may irrecoverably break various environments, - # e.g. MPI. - # - # Since the late-start logging is an optional 'quality-of-life' - # feature for interactive use, do not do it unless there is (weak) - # evidence of interactive use. - try: self.late_start_log_thread.start() except RuntimeError: -- GitLab