X-Git-Url: https://wannabe.guru.org/gitweb/?a=blobdiff_plain;f=lockfile.py;fp=lockfile.py;h=ca190df09f9245bca7153945f0fee61859daa1d7;hb=5f75cf834725ac26b289cc5f157af0cb71cd5f0e;hp=b6a832ee0e3a9c5eadb27cc3b1955538fb49c345;hpb=ba223f821df1e9b8abbb6f6d23d5ba92c5a70b05;p=python_utils.git diff --git a/lockfile.py b/lockfile.py index b6a832e..ca190df 100644 --- a/lockfile.py +++ b/lockfile.py @@ -9,9 +9,20 @@ import signal import sys from typing import Optional +import config import decorator_utils +cfg = config.add_commandline_args( + f'Lockfile ({__file__})', + 'Args related to lockfiles') +cfg.add_argument( + '--lockfile_held_duration_warning_threshold_sec', + type=float, + default=10.0, + metavar='SECONDS', + help='If a lock is held for longer than this threshold we log a warning' +) logger = logging.getLogger(__name__) @@ -75,7 +86,7 @@ class LockFile(object): return True except OSError: pass - logger.debug(f'Failed; I could not acquire {self.lockfile}.') + logger.warning(f'Could not acquire {self.lockfile}.') return False def acquire_with_retries( @@ -108,12 +119,19 @@ class LockFile(object): def __enter__(self): if self.acquire_with_retries(): + self.locktime = datetime.datetime.now().timestamp() return self msg = f"Couldn't acquire {self.lockfile}; giving up." logger.warning(msg) raise LockFileException(msg) def __exit__(self, type, value, traceback): + if self.locktime: + ts = datetime.datetime.now().timestamp() + duration = ts - self.locktime + if duration >= config.config['lockfile_held_duration_warning_threshold_sec']: + str_duration = datetime_utils.describe_duration_briefly(duration) + logger.warning(f'Held {self.lockfile} for {str_duration}') self.release() def __del__(self): @@ -151,15 +169,16 @@ class LockFile(object): try: os.kill(contents.pid, 0) except OSError: - logger.debug('The pid seems stale; killing the lock.') + logger.warning(f'Lockfile {self.lockfile}\'s pid ({contents.pid}) is stale; ' + + 'force acquiring') self.release() # Has the lock expiration expired? if contents.expiration_timestamp is not None: now = datetime.datetime.now().timestamp() if now > contents.expiration_datetime: - logger.debug('The expiration time has passed; ' + - 'killing the lock') + logger.warning(f'Lockfile {self.lockfile} expiration time has passed; ' + + 'force acquiring') self.release() except Exception: pass