1# Copyright 2025 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4""" Writes logs to indicate a long-run process to avoid being killed by luci. 5""" 6 7import logging 8 9from contextlib import AbstractContextManager 10from threading import Timer 11 12 13class RepeatingLog(AbstractContextManager): 14 """Starts writing the log once a while after the initial wait. Luci swarming 15 considers a long run job being dead if it does not output for a while. 16 It's an issue for tasks like video analysis which may take up to several 17 minutes. So this is a simple way to workaround the restriction.""" 18 19 def __init__(self, msg: str): 20 self.msg = msg 21 self.counter = 0 22 self.timer = None 23 24 def __enter__(self): 25 self._schedule() 26 27 def _schedule(self) -> None: 28 self.timer = Timer(15, self._log_and_schedule) 29 self.timer.start() 30 31 def _log_and_schedule(self) -> None: 32 self.counter += 1 33 # Use warning to avoid being ignored by the log-level. 34 logging.warning('[After %s seconds] - %s', self.counter * 15, self.msg) 35 self._schedule() 36 37 def __exit__(self, exc_type, exc_value, traceback): 38 if self.timer: 39 self.timer.cancel() 40