mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-13 07:47:14 +03:00
Re-factor JournalLock.obtain_lock() for 'ALREADY_LOCKED' test.
This splits the code for opening the lockfile away from that for actually obtaining the lock. It enables a test for trying to lock again with the same file handle.
This commit is contained in:
parent
70bdc5e0e9
commit
cfdf9fbf20
@ -53,16 +53,9 @@ class JournalLock:
|
||||
except Exception:
|
||||
logger.exception("Couldn't make pathlib.Path from journal_dir")
|
||||
|
||||
def obtain_lock(self) -> JournalLockResult:
|
||||
"""
|
||||
Attempt to obtain a lock on the journal directory.
|
||||
|
||||
:return: LockResult - See the class Enum definition
|
||||
"""
|
||||
if self.journal_dir_path is None:
|
||||
return JournalLockResult.JOURNALDIR_IS_NONE
|
||||
|
||||
self.journal_dir_lockfile_name = self.journal_dir_path / 'edmc-journal-lock.txt'
|
||||
def open_journal_dir_lockfile(self) -> bool:
|
||||
"""Open journal_dir lockfile ready for locking."""
|
||||
self.journal_dir_lockfile_name = self.journal_dir_path / 'edmc-journal-lock.txt' # type: ignore
|
||||
logger.trace(f'journal_dir_lockfile_name = {self.journal_dir_lockfile_name!r}')
|
||||
try:
|
||||
self.journal_dir_lockfile = open(self.journal_dir_lockfile_name, mode='w+', encoding='utf-8')
|
||||
@ -72,8 +65,35 @@ class JournalLock:
|
||||
except Exception as e: # For remote FS this could be any of a wide range of exceptions
|
||||
logger.warning(f"Couldn't open \"{self.journal_dir_lockfile_name}\" for \"w+\""
|
||||
f" Aborting duplicate process checks: {e!r}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def obtain_lock(self) -> JournalLockResult:
|
||||
"""
|
||||
Attempt to obtain a lock on the journal directory.
|
||||
|
||||
:return: LockResult - See the class Enum definition
|
||||
"""
|
||||
if self.journal_dir_path is None:
|
||||
return JournalLockResult.JOURNALDIR_IS_NONE
|
||||
|
||||
if not self.open_journal_dir_lockfile():
|
||||
return JournalLockResult.JOURNALDIR_READONLY
|
||||
|
||||
return self._obtain_lock()
|
||||
|
||||
def _obtain_lock(self) -> JournalLockResult:
|
||||
"""
|
||||
Actual code for obtaining a lock.
|
||||
|
||||
This is split out so tests can call *just* it, without the attempt
|
||||
at opening the file. If we call open_journal_dir_lockfile() we
|
||||
re-use self.journal_dir_lockfile and in the process close the
|
||||
previous handle stored in it and thus release the lock.
|
||||
|
||||
:return: LockResult - See the class Enum definition
|
||||
"""
|
||||
if platform == 'win32':
|
||||
logger.trace('win32, using msvcrt')
|
||||
# win32 doesn't have fcntl, so we have to use msvcrt
|
||||
|
@ -182,3 +182,13 @@ class TestJournalLock:
|
||||
os.chmod(tmpdir, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
|
||||
|
||||
assert locked == JournalLockResult.JOURNALDIR_READONLY
|
||||
|
||||
def test_obtain_lock_already_locked(self, mock_journaldir: py_path_local_LocalPath):
|
||||
"""Test JournalLock.obtain_lock() with tmpdir."""
|
||||
jlock = JournalLock()
|
||||
|
||||
locked = jlock.obtain_lock()
|
||||
assert locked == JournalLockResult.LOCKED
|
||||
# Now attempt to lock again, but only that.
|
||||
second_attempt = jlock._obtain_lock()
|
||||
assert second_attempt == JournalLockResult.ALREADY_LOCKED
|
||||
|
Loading…
x
Reference in New Issue
Block a user