diff options
author | Harmen Stoppels <harmenstoppels@gmail.com> | 2022-10-24 11:54:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-24 11:54:49 +0200 |
commit | d67b12eb7934637f119ed7ad6f80f3d5f574895b (patch) | |
tree | 1af6dba5eb03d60780ca923308fac9365eaabd6f /lib/spack/llnl/util | |
parent | 7d99fbcafd4720babe2a0d325df099ed9056f5e1 (diff) | |
download | spack-d67b12eb7934637f119ed7ad6f80f3d5f574895b.tar.gz spack-d67b12eb7934637f119ed7ad6f80f3d5f574895b.tar.bz2 spack-d67b12eb7934637f119ed7ad6f80f3d5f574895b.tar.xz spack-d67b12eb7934637f119ed7ad6f80f3d5f574895b.zip |
locks: improved errors (#33477)
Instead of showing
```
==> Error: Timed out waiting for a write lock.
```
show
```
==> Error: Timed out waiting for a write lock after 1.200ms and 4 attempts on file: /some/file
```
s.t. we actually get to see where acquiring a lock failed even when not
running in debug mode.
And use pretty time units everywhere, so we don't get 1.45e-9 seconds
but 1.450ns etc.
Diffstat (limited to 'lib/spack/llnl/util')
-rw-r--r-- | lib/spack/llnl/util/lang.py | 20 | ||||
-rw-r--r-- | lib/spack/llnl/util/lock.py | 22 |
2 files changed, 38 insertions, 4 deletions
diff --git a/lib/spack/llnl/util/lang.py b/lib/spack/llnl/util/lang.py index 76b161cbbe..f1a0b7ba31 100644 --- a/lib/spack/llnl/util/lang.py +++ b/lib/spack/llnl/util/lang.py @@ -749,6 +749,26 @@ def pretty_string_to_date(date_str, now=None): raise ValueError(msg) +def pretty_seconds(seconds): + """Seconds to string with appropriate units + + Arguments: + seconds (float): Number of seconds + + Returns: + str: Time string with units + """ + if seconds >= 1: + value, unit = seconds, "s" + elif seconds >= 1e-3: + value, unit = seconds * 1e3, "ms" + elif seconds >= 1e-6: + value, unit = seconds * 1e6, "us" + else: + value, unit = seconds * 1e9, "ns" + return "%.3f%s" % (value, unit) + + class RequiredAttributeError(ValueError): def __init__(self, message): super(RequiredAttributeError, self).__init__(message) diff --git a/lib/spack/llnl/util/lock.py b/lib/spack/llnl/util/lock.py index 6dfba50abb..9c3bcd7a91 100644 --- a/lib/spack/llnl/util/lock.py +++ b/lib/spack/llnl/util/lock.py @@ -12,6 +12,7 @@ from datetime import datetime from typing import Dict, Tuple # novm import llnl.util.tty as tty +from llnl.util.lang import pretty_seconds import spack.util.string @@ -166,7 +167,7 @@ def _attempts_str(wait_time, nattempts): return "" attempts = spack.util.string.plural(nattempts, "attempt") - return " after {0:0.2f}s and {1}".format(wait_time, attempts) + return " after {} and {}".format(pretty_seconds(wait_time), attempts) class LockType(object): @@ -318,8 +319,8 @@ class Lock(object): raise LockROFileError(self.path) self._log_debug( - "{0} locking [{1}:{2}]: timeout {3} sec".format( - op_str.lower(), self._start, self._length, timeout + "{} locking [{}:{}]: timeout {}".format( + op_str.lower(), self._start, self._length, pretty_seconds(timeout or 0) ) ) @@ -340,7 +341,8 @@ class Lock(object): total_wait_time = time.time() - start_time return total_wait_time, num_attempts - raise LockTimeoutError("Timed out waiting for a {0} lock.".format(op_str.lower())) + total_wait_time = time.time() - start_time + raise LockTimeoutError(op_str.lower(), self.path, total_wait_time, num_attempts) def _poll_lock(self, op): """Attempt to acquire the lock in a non-blocking manner. Return whether @@ -780,6 +782,18 @@ class LockLimitError(LockError): class LockTimeoutError(LockError): """Raised when an attempt to acquire a lock times out.""" + def __init__(self, lock_type, path, time, attempts): + fmt = "Timed out waiting for a {} lock after {}.\n Made {} {} on file: {}" + super(LockTimeoutError, self).__init__( + fmt.format( + lock_type, + pretty_seconds(time), + attempts, + "attempt" if attempts == 1 else "attempts", + path, + ) + ) + class LockUpgradeError(LockError): """Raised when unable to upgrade from a read to a write lock.""" |