mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
fix(conftest): use synchronization locks for setup_database
We were running into data race issues where the `fn.is_file()` check would occur twice before writing the file in the `else` clause. For this reason, a new aurweb.lock.Lock class has been added which doubles as a thread and process lock. We can use this elsewhere in the future, but we are also able to use it to solve this kind of data race issue. That being said, we still need the lock file state to tell us when the first caller acquired the lock. Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
parent
155aa47a1a
commit
4b0cb0721d
3 changed files with 95 additions and 24 deletions
32
aurweb/testing/filelock.py
Normal file
32
aurweb/testing/filelock.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
import hashlib
|
||||
import os
|
||||
|
||||
from typing import Callable
|
||||
|
||||
from posix_ipc import O_CREAT, Semaphore
|
||||
|
||||
from aurweb import logging
|
||||
|
||||
logger = logging.get_logger(__name__)
|
||||
|
||||
|
||||
def default_on_create(path):
|
||||
logger.info(f"Filelock at {path} acquired.")
|
||||
|
||||
|
||||
class FileLock:
|
||||
def __init__(self, tmpdir, name: str):
|
||||
self.root = tmpdir
|
||||
self.path = str(self.root / name)
|
||||
self._file = str(self.root / (f"{name}.1"))
|
||||
|
||||
def lock(self, on_create: Callable = default_on_create):
|
||||
hash = hashlib.sha1(self.path.encode()).hexdigest()
|
||||
with Semaphore(f"/{hash}-lock", flags=O_CREAT, initial_value=1):
|
||||
retval = os.path.exists(self._file)
|
||||
if not retval:
|
||||
with open(self._file, "w") as f:
|
||||
f.write("1")
|
||||
on_create(self.path)
|
||||
|
||||
return retval
|
Loading…
Add table
Add a link
Reference in a new issue