summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThomas Waldmann <tw@waldmann-edv.de>2023-11-16 14:40:06 +0100
committerThomas Waldmann <tw@waldmann-edv.de>2023-11-16 15:59:28 +0100
commitec17b00411a2a9566fea2756c5f6f9ee7b8717c4 (patch)
tree063f170922db1e58bda943dc995ef517caacc379 /src
parent2341ba62d39d485fd7199105812792d24a4772b8 (diff)
LockRoster.modify: no KeyError if element was already gone, fixes #7937
The intention of LockRoster.modify(key, REMOVE) is to remove self.id. Using set.discard will just ignore it if self.id is not present there anymore. Previously, using set.remove triggered a KeyError that has been frequently seen in tracebacks of teardowns involving Repository.__del__ and Repository.__exit__. I added a REMOVE2 op to serve one caller that needs to get the KeyError if self.id was not present. Thanks to @herrmanntom for the workaround!
Diffstat (limited to 'src')
-rw-r--r--src/borg/locking.py9
-rw-r--r--src/borg/testsuite/locking.py2
2 files changed, 8 insertions, 3 deletions
diff --git a/src/borg/locking.py b/src/borg/locking.py
index 4192f1f10..7ddb6df74 100644
--- a/src/borg/locking.py
+++ b/src/borg/locking.py
@@ -8,7 +8,7 @@ from . import platform
from .helpers import Error, ErrorWithTraceback
from .logger import create_logger
-ADD, REMOVE = 'add', 'remove'
+ADD, REMOVE, REMOVE2 = 'add', 'remove', 'remove2'
SHARED, EXCLUSIVE = 'shared', 'exclusive'
logger = create_logger(__name__)
@@ -313,6 +313,11 @@ class LockRoster:
if op == ADD:
elements.add(self.id)
elif op == REMOVE:
+ # note: we ignore it if the element is already not present anymore.
+ # this has been frequently seen in teardowns involving Repository.__del__ and Repository.__exit__.
+ elements.discard(self.id)
+ elif op == REMOVE2:
+ # needed for callers that do not want to ignore.
elements.remove(self.id)
else:
raise ValueError('Unknown LockRoster op %r' % op)
@@ -327,7 +332,7 @@ class LockRoster:
killing, self.kill_stale_locks = self.kill_stale_locks, False
try:
try:
- self.modify(key, REMOVE)
+ self.modify(key, REMOVE2)
except KeyError:
# entry was not there, so no need to add a new one, but still update our id
self.id = new_id
diff --git a/src/borg/testsuite/locking.py b/src/borg/testsuite/locking.py
index b8fb67797..5c593bdda 100644
--- a/src/borg/testsuite/locking.py
+++ b/src/borg/testsuite/locking.py
@@ -241,7 +241,7 @@ class TestLock:
assert roster.get(SHARED) == {our_id}
assert roster.get(EXCLUSIVE) == set()
assert roster.get(SHARED) == set()
- with pytest.raises(KeyError):
+ with pytest.raises(NotLocked):
dead_lock.release()
with Lock(lockpath, id=cant_know_if_dead_id, exclusive=True):