mirror of
https://github.com/borgbackup/borg.git
synced 2026-10-12 02:11:36 +00:00
storelocking: check for other locks at least once before an exclusive acquire times out
This commit is contained in:
@@ -463,12 +463,15 @@ class Lock:
|
||||
if self.is_exclusive:
|
||||
if len(exclusive_locks) == 1 and exclusive_locks[0]["key"] == key:
|
||||
logger.debug("LOCK-ACQUIRE: we are the only exclusive lock!")
|
||||
while time.monotonic() - started < self.timeout:
|
||||
# check at least once, even if creating our lock already used up the timeout.
|
||||
while True:
|
||||
locks = self._find_locks(only_exclusive=False)
|
||||
if len(locks) == 1 and locks[0]["key"] == key:
|
||||
logger.debug("LOCK-ACQUIRE: success! no non-exclusive locks are left!")
|
||||
return self
|
||||
blocking_locks = [lock for lock in locks if lock["key"] != key]
|
||||
if time.monotonic() - started >= self.timeout:
|
||||
break
|
||||
self._log_blocking_locks(blocking_locks)
|
||||
time.sleep(self.other_locks_go_away_delay)
|
||||
logger.debug("LOCK-ACQUIRE: timeout while waiting for non-exclusive locks to go away.")
|
||||
|
||||
@@ -92,6 +92,19 @@ class TestLock:
|
||||
assert len(locks) == 1 # only the non-exclusive lock of ID1 is left
|
||||
assert not any(lock["exclusive"] for lock in locks.values())
|
||||
|
||||
def test_exclusive_lock_on_slow_store(self, lockstore, monkeypatch):
|
||||
# An exclusive lock is acquired if no other lock exists, even if writing our lock object
|
||||
# takes longer than the timeout.
|
||||
orig_store = lockstore.store
|
||||
|
||||
def slow_store(name, value):
|
||||
time.sleep(0.2)
|
||||
return orig_store(name, value)
|
||||
|
||||
monkeypatch.setattr(lockstore, "store", slow_store)
|
||||
with Lock(lockstore, exclusive=True, id=ID1, timeout=0.1) as lock:
|
||||
assert lock.got_exclusive_lock()
|
||||
|
||||
def test_double_nonexclusive_lock_succeeds(self, lockstore):
|
||||
with Lock(lockstore, exclusive=False, id=ID1):
|
||||
with Lock(lockstore, exclusive=False, id=ID2):
|
||||
|
||||
Reference in New Issue
Block a user