chia-blockchain/chia/util/lock.py
dustinface e5297f411d
util: Unify lockfile handling (#12541)
* util: Unify lockfile handling

This patch:
- Renames `util.lock.lock_by_path` to `util.lock.lock_path` and improves it by using `FileLock`
- Unifies all places where we create lock files to use `chia.util.lock.lock_path`
- Changes the daemon lockfile from `start-daemon.launching` to `daemon.lock` like we have it with all `<service>.lock` in the `run` folder
- Drops the `fastener` dependency

* Move the not keyring related sync tests into `test_lockfile.py`
2022-08-04 12:59:39 -05:00

48 lines
1.3 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from types import TracebackType
from typing import Optional, Type
from filelock import BaseFileLock, FileLock, Timeout
from typing_extensions import final
class LockfileError(Exception):
pass
@final
@dataclass(frozen=True)
class Lockfile:
_lock: BaseFileLock
timeout: float
poll_interval: float
@classmethod
def create(cls, path: Path, timeout: float = -1, poll_interval: float = 0.05) -> Lockfile:
path.parent.mkdir(parents=True, exist_ok=True)
return cls(_lock=FileLock(path.with_name(path.name + ".lock")), timeout=timeout, poll_interval=poll_interval)
def __enter__(self) -> Lockfile:
self.acquire(timeout=self.timeout, poll_interval=self.poll_interval)
return self
def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc: Optional[BaseException],
traceback: Optional[TracebackType],
) -> None:
self.release()
def acquire(self, timeout: float, poll_interval: float) -> None:
try:
self._lock.acquire(timeout=timeout, poll_interval=poll_interval)
except Timeout as e:
raise LockfileError(e) from e
def release(self) -> None:
self._lock.release()