From d78d631ed7c5e4ebfcf8858f9c305aa690cfc2e1 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Wed, 19 Jul 2023 13:48:42 -0500 Subject: [PATCH] Avoid a reference cycle in ProcessLogger --- pytools/__init__.py | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/pytools/__init__.py b/pytools/__init__.py index a2b2d410..8f3c9739 100644 --- a/pytools/__init__.py +++ b/pytools/__init__.py @@ -2571,6 +2571,18 @@ def __repr__(self): # {{{ log utilities +def _log_start_if_long(logger, sleep_duration, done_indicator, + noisy_level, description): + from time import sleep + sleep(sleep_duration) + + if not done_indicator[0]: + logger.log( + noisy_level, "%s: started %.gs ago", + description, + sleep_duration) + + class ProcessLogger: # pylint: disable=too-many-instance-attributes """Logs the completion time of a (presumably) lengthy process to :mod:`logging`. Only uses a high log level if the process took perceptible time. @@ -2595,13 +2607,16 @@ def __init__( # pylint: disable=too-many-arguments 0.3 if long_threshold_seconds is None else long_threshold_seconds) self.logger.log(self.silent_level, "%s: start", self.description) - self.is_done = False + self._done_indicator = [False] import threading - self.late_start_log_thread = threading.Thread(target=self._log_start_if_long) + self.late_start_log_thread = threading.Thread( + target=_log_start_if_long, + args=(logger, 10*self.long_threshold_seconds, self._done_indicator, + self.noisy_level, self.description), - # Do not delay interpreter exit if thread not finished. - self.late_start_log_thread.daemon = True + # Do not delay interpreter exit if thread not finished. + daemon=True) # https://github.com/firedrakeproject/firedrake/issues/1422 # Starting a thread may irrecoverably break various environments, @@ -2639,22 +2654,10 @@ def __init__( # pylint: disable=too-many-arguments self.timer = ProcessTimer() - def _log_start_if_long(self): - from time import sleep - - sleep_duration = 10*self.long_threshold_seconds - sleep(sleep_duration) - - if not self.is_done: - self.logger.log( - self.noisy_level, "%s: started %.gs ago", - self.description, - sleep_duration) - def done( # pylint: disable=keyword-arg-before-vararg self, extra_msg=None, *extra_fmt_args): self.timer.done() - self.is_done = True + self._done_indicator[0] = True completion_level = ( self.noisy_level