ddp_utils.runtime.lock¶
import ddp_utils.runtime.lock
Provide an interprocess lock based on atomic lock-file creation.
FileLock records owner metadata, detects stale locks, and supports explicit
and context-managed acquisition lifecycles.
Examples
Use this public operation:
from ddp_utils.runtime.lock import FileLock
lock = FileLock("example", "update", create_now=False)
- class ddp_utils.runtime.lock.FileLock(namespace: str, name: str, *, timeout: float | None = 30.0, poll_interval: float = 0.2, stale_after: float | None = None, create_now: bool = True)¶
Bases:
objectCross-process file lock based on atomic lock-file creation.
The lock is stored under the namespace
locksroot. The lock file contains metadata about the owning process. Lock acquisition is based on atomic file creation usingO_CREAT | O_EXCL, which is supported by the operating system and is sufficient for many production workflows where a lightweight advisory lock is needed.Typical use cases:
preventing two processes from downloading the same driver simultaneously;
serializing access to a shared cache directory;
guarding write operations to shared runtime artifacts.
The lock file layout is plain text with simple key/value pairs.
Parameters
Name
Type
Description
namespace
str
Namespace of the owning library or module.
name
str
Logical lock name. It is normalized into a filesystem-safe file name.
timeout
Optional[float]
Maximum number of seconds to wait for acquiring the lock. If
None, wait indefinitely.poll_interval
float
Delay between acquisition attempts.
stale_after
Optional[float]
If provided, a lock file older than this number of seconds may be considered stale and removed before retrying acquisition.
create_now
bool
If
True, the lock directory is created immediately.Raises
Exception
Description
ValueError
If
nameis empty.Examples
Use this public operation:
instance = FileLock(...)
Configure one namespaced lock and its acquisition policy.
The lock itself is not acquired during initialization. Resolving its path ensures the namespace lock directory exists even when
create_nowis false.Parameters
Name
Type
Description
namespace
str
Non-empty runtime namespace containing the lock.
name
str
Logical lock name normalized for use as a filename.
timeout
Optional[float]
Maximum acquisition wait in seconds, or
Noneto wait indefinitely.poll_interval
float
Delay in seconds between acquisition attempts.
stale_after
Optional[float]
Optional age in seconds after which an existing lock may be removed as stale.
create_now
bool
Create the complete runtime directory layout eagerly. The lock directory is still created while resolving
path.Raises
Exception
Description
ValueError
namespaceornameis empty or invalid.OSError
The runtime lock directory cannot be created.
Examples
Configure a bounded lock without acquiring it:
lock = FileLock("reports", "refresh", timeout=5.0)
- property path: Path¶
Return the lock file path.
Returns
Path to the lock file.
Examples
Use this public operation:
result = instance.path()
- property acquired: bool¶
Return whether the current instance owns the lock.
Returns
Trueif the lock is currently held by this instance.Examples
Use this public operation:
result = instance.acquired()
- acquire() bool¶
Acquire the lock.
If a stale lock policy is configured through
stale_after, stale locks are removed before retrying acquisition.Returns
Type
Description
bool
Trueif the lock was acquired.Raises
Exception
Description
TimeoutError
If the timeout is reached before acquiring the lock.
Examples
Use this public operation:
result = instance.acquire()
- release() None¶
Release the lock if it is owned by this instance.
The method is safe to call multiple times.
Examples
Use this public operation:
result = instance.release()
- force_release() None¶
Remove the lock file unconditionally.
This should be used only in controlled scenarios when a caller knows that the current lock file is no longer valid.
Examples
Use this public operation:
result = instance.force_release()
- exists() bool¶
Check whether a lock file currently exists.
Returns
Type
Description
bool
Trueif the lock file exists.Examples
Use this public operation:
result = instance.exists()
- age_seconds() float | None¶
Return the current lock age in seconds.
Returns
Type
Description
float | None
Lock age in seconds, or
Noneif the lock does not exist.Examples
Use this public operation:
result = instance.age_seconds()
- is_stale() bool¶
Check whether the lock is stale according to
stale_after.Returns
Type
Description
bool
Trueif the lock exists and is older thanstale_after.Examples
Use this public operation:
result = instance.is_stale()
- read_metadata() dict[str, str]¶
Read lock metadata from the lock file.
Returns
Type
Description
dict[str, str]
Dictionary of key/value pairs. Empty dict if file does not exist or cannot be parsed.
Examples
Use this public operation:
result = instance.read_metadata()