Переглянути джерело

rename UpgradableLock to Lock

lock upgrading is troublesome / may deadlock, do not advertise it.
Thomas Waldmann 9 роки тому
батько
коміт
d3d51e12ea
6 змінених файлів з 29 додано та 30 видалено
  1. 3 3
      borg/cache.py
  2. 3 3
      borg/locking.py
  3. 3 3
      borg/repository.py
  4. 16 16
      borg/testsuite/locking.py
  5. 1 1
      borg/testsuite/repository.py
  6. 3 4
      borg/upgrader.py

+ 3 - 3
borg/cache.py

@@ -11,7 +11,7 @@ from .logger import create_logger
 logger = create_logger()
 logger = create_logger()
 from .helpers import Error, get_cache_dir, decode_dict, int_to_bigint, \
 from .helpers import Error, get_cache_dir, decode_dict, int_to_bigint, \
     bigint_to_int, format_file_size, yes
     bigint_to_int, format_file_size, yes
-from .locking import UpgradableLock
+from .locking import Lock
 from .hashindex import ChunkIndex
 from .hashindex import ChunkIndex
 
 
 import msgpack
 import msgpack
@@ -35,7 +35,7 @@ class Cache:
     @staticmethod
     @staticmethod
     def break_lock(repository, path=None):
     def break_lock(repository, path=None):
         path = path or os.path.join(get_cache_dir(), hexlify(repository.id).decode('ascii'))
         path = path or os.path.join(get_cache_dir(), hexlify(repository.id).decode('ascii'))
-        UpgradableLock(os.path.join(path, 'lock'), exclusive=True).break_lock()
+        Lock(os.path.join(path, 'lock'), exclusive=True).break_lock()
 
 
     @staticmethod
     @staticmethod
     def destroy(repository, path=None):
     def destroy(repository, path=None):
@@ -152,7 +152,7 @@ Chunk index:    {0.total_unique_chunks:20d} {0.total_chunks:20d}"""
     def open(self, lock_wait=None):
     def open(self, lock_wait=None):
         if not os.path.isdir(self.path):
         if not os.path.isdir(self.path):
             raise Exception('%s Does not look like a Borg cache' % self.path)
             raise Exception('%s Does not look like a Borg cache' % self.path)
-        self.lock = UpgradableLock(os.path.join(self.path, 'lock'), exclusive=True, timeout=lock_wait).acquire()
+        self.lock = Lock(os.path.join(self.path, 'lock'), exclusive=True, timeout=lock_wait).acquire()
         self.rollback()
         self.rollback()
 
 
     def close(self):
     def close(self):

+ 3 - 3
borg/locking.py

@@ -217,7 +217,7 @@ class LockRoster:
         self.save(roster)
         self.save(roster)
 
 
 
 
-class UpgradableLock:
+class Lock:
     """
     """
     A Lock for a resource that can be accessed in a shared or exclusive way.
     A Lock for a resource that can be accessed in a shared or exclusive way.
     Typically, write access to a resource needs an exclusive lock (1 writer,
     Typically, write access to a resource needs an exclusive lock (1 writer,
@@ -226,7 +226,7 @@ class UpgradableLock:
 
 
     If possible, try to use the contextmanager here like::
     If possible, try to use the contextmanager here like::
 
 
-        with UpgradableLock(...) as lock:
+        with Lock(...) as lock:
             ...
             ...
 
 
     This makes sure the lock is released again if the block is left, no
     This makes sure the lock is released again if the block is left, no
@@ -242,7 +242,7 @@ class UpgradableLock:
         self._roster = LockRoster(path + '.roster', id=id)
         self._roster = LockRoster(path + '.roster', id=id)
         # an exclusive lock, used for:
         # an exclusive lock, used for:
         # - holding while doing roster queries / updates
         # - holding while doing roster queries / updates
-        # - holding while the UpgradableLock itself is exclusive
+        # - holding while the Lock instance itself is exclusive
         self._lock = ExclusiveLock(path + '.exclusive', id=id, timeout=timeout)
         self._lock = ExclusiveLock(path + '.exclusive', id=id, timeout=timeout)
 
 
     def __enter__(self):
     def __enter__(self):

+ 3 - 3
borg/repository.py

@@ -14,7 +14,7 @@ from zlib import crc32
 import msgpack
 import msgpack
 from .helpers import Error, ErrorWithTraceback, IntegrityError, Location, ProgressIndicatorPercent
 from .helpers import Error, ErrorWithTraceback, IntegrityError, Location, ProgressIndicatorPercent
 from .hashindex import NSIndex
 from .hashindex import NSIndex
-from .locking import UpgradableLock, LockError, LockErrorT
+from .locking import Lock, LockError, LockErrorT
 from .lrucache import LRUCache
 from .lrucache import LRUCache
 from .platform import sync_dir
 from .platform import sync_dir
 
 
@@ -161,14 +161,14 @@ class Repository:
         return self.get_index_transaction_id()
         return self.get_index_transaction_id()
 
 
     def break_lock(self):
     def break_lock(self):
-        UpgradableLock(os.path.join(self.path, 'lock')).break_lock()
+        Lock(os.path.join(self.path, 'lock')).break_lock()
 
 
     def open(self, path, exclusive, lock_wait=None, lock=True):
     def open(self, path, exclusive, lock_wait=None, lock=True):
         self.path = path
         self.path = path
         if not os.path.isdir(path):
         if not os.path.isdir(path):
             raise self.DoesNotExist(path)
             raise self.DoesNotExist(path)
         if lock:
         if lock:
-            self.lock = UpgradableLock(os.path.join(path, 'lock'), exclusive, timeout=lock_wait).acquire()
+            self.lock = Lock(os.path.join(path, 'lock'), exclusive, timeout=lock_wait).acquire()
         else:
         else:
             self.lock = None
             self.lock = None
         self.config = ConfigParser(interpolation=None)
         self.config = ConfigParser(interpolation=None)

+ 16 - 16
borg/testsuite/locking.py

@@ -2,7 +2,7 @@ import time
 
 
 import pytest
 import pytest
 
 
-from ..locking import get_id, TimeoutTimer, ExclusiveLock, UpgradableLock, LockRoster, \
+from ..locking import get_id, TimeoutTimer, ExclusiveLock, Lock, LockRoster, \
                       ADD, REMOVE, SHARED, EXCLUSIVE, LockTimeout
                       ADD, REMOVE, SHARED, EXCLUSIVE, LockTimeout
 
 
 
 
@@ -58,36 +58,36 @@ class TestExclusiveLock:
                 ExclusiveLock(lockpath, id=ID2, timeout=0.1).acquire()
                 ExclusiveLock(lockpath, id=ID2, timeout=0.1).acquire()
 
 
 
 
-class TestUpgradableLock:
+class TestLock:
     def test_shared(self, lockpath):
     def test_shared(self, lockpath):
-        lock1 = UpgradableLock(lockpath, exclusive=False, id=ID1).acquire()
-        lock2 = UpgradableLock(lockpath, exclusive=False, id=ID2).acquire()
+        lock1 = Lock(lockpath, exclusive=False, id=ID1).acquire()
+        lock2 = Lock(lockpath, exclusive=False, id=ID2).acquire()
         assert len(lock1._roster.get(SHARED)) == 2
         assert len(lock1._roster.get(SHARED)) == 2
         assert len(lock1._roster.get(EXCLUSIVE)) == 0
         assert len(lock1._roster.get(EXCLUSIVE)) == 0
         lock1.release()
         lock1.release()
         lock2.release()
         lock2.release()
 
 
     def test_exclusive(self, lockpath):
     def test_exclusive(self, lockpath):
-        with UpgradableLock(lockpath, exclusive=True, id=ID1) as lock:
+        with Lock(lockpath, exclusive=True, id=ID1) as lock:
             assert len(lock._roster.get(SHARED)) == 0
             assert len(lock._roster.get(SHARED)) == 0
             assert len(lock._roster.get(EXCLUSIVE)) == 1
             assert len(lock._roster.get(EXCLUSIVE)) == 1
 
 
     def test_upgrade(self, lockpath):
     def test_upgrade(self, lockpath):
-        with UpgradableLock(lockpath, exclusive=False) as lock:
+        with Lock(lockpath, exclusive=False) as lock:
             lock.upgrade()
             lock.upgrade()
             lock.upgrade()  # NOP
             lock.upgrade()  # NOP
             assert len(lock._roster.get(SHARED)) == 0
             assert len(lock._roster.get(SHARED)) == 0
             assert len(lock._roster.get(EXCLUSIVE)) == 1
             assert len(lock._roster.get(EXCLUSIVE)) == 1
 
 
     def test_downgrade(self, lockpath):
     def test_downgrade(self, lockpath):
-        with UpgradableLock(lockpath, exclusive=True) as lock:
+        with Lock(lockpath, exclusive=True) as lock:
             lock.downgrade()
             lock.downgrade()
             lock.downgrade()  # NOP
             lock.downgrade()  # NOP
             assert len(lock._roster.get(SHARED)) == 1
             assert len(lock._roster.get(SHARED)) == 1
             assert len(lock._roster.get(EXCLUSIVE)) == 0
             assert len(lock._roster.get(EXCLUSIVE)) == 0
 
 
     def test_got_exclusive_lock(self, lockpath):
     def test_got_exclusive_lock(self, lockpath):
-        lock = UpgradableLock(lockpath, exclusive=True, id=ID1)
+        lock = Lock(lockpath, exclusive=True, id=ID1)
         assert not lock.got_exclusive_lock()
         assert not lock.got_exclusive_lock()
         lock.acquire()
         lock.acquire()
         assert lock.got_exclusive_lock()
         assert lock.got_exclusive_lock()
@@ -95,23 +95,23 @@ class TestUpgradableLock:
         assert not lock.got_exclusive_lock()
         assert not lock.got_exclusive_lock()
 
 
     def test_break(self, lockpath):
     def test_break(self, lockpath):
-        lock = UpgradableLock(lockpath, exclusive=True, id=ID1).acquire()
+        lock = Lock(lockpath, exclusive=True, id=ID1).acquire()
         lock.break_lock()
         lock.break_lock()
         assert len(lock._roster.get(SHARED)) == 0
         assert len(lock._roster.get(SHARED)) == 0
         assert len(lock._roster.get(EXCLUSIVE)) == 0
         assert len(lock._roster.get(EXCLUSIVE)) == 0
-        with UpgradableLock(lockpath, exclusive=True, id=ID2):
+        with Lock(lockpath, exclusive=True, id=ID2):
             pass
             pass
 
 
     def test_timeout(self, lockpath):
     def test_timeout(self, lockpath):
-        with UpgradableLock(lockpath, exclusive=False, id=ID1):
+        with Lock(lockpath, exclusive=False, id=ID1):
             with pytest.raises(LockTimeout):
             with pytest.raises(LockTimeout):
-                UpgradableLock(lockpath, exclusive=True, id=ID2, timeout=0.1).acquire()
-        with UpgradableLock(lockpath, exclusive=True, id=ID1):
+                Lock(lockpath, exclusive=True, id=ID2, timeout=0.1).acquire()
+        with Lock(lockpath, exclusive=True, id=ID1):
             with pytest.raises(LockTimeout):
             with pytest.raises(LockTimeout):
-                UpgradableLock(lockpath, exclusive=False, id=ID2, timeout=0.1).acquire()
-        with UpgradableLock(lockpath, exclusive=True, id=ID1):
+                Lock(lockpath, exclusive=False, id=ID2, timeout=0.1).acquire()
+        with Lock(lockpath, exclusive=True, id=ID1):
             with pytest.raises(LockTimeout):
             with pytest.raises(LockTimeout):
-                UpgradableLock(lockpath, exclusive=True, id=ID2, timeout=0.1).acquire()
+                Lock(lockpath, exclusive=True, id=ID2, timeout=0.1).acquire()
 
 
 
 
 @pytest.fixture()
 @pytest.fixture()

+ 1 - 1
borg/testsuite/repository.py

@@ -6,7 +6,7 @@ from unittest.mock import patch
 
 
 from ..hashindex import NSIndex
 from ..hashindex import NSIndex
 from ..helpers import Location, IntegrityError
 from ..helpers import Location, IntegrityError
-from ..locking import UpgradableLock, LockFailed
+from ..locking import Lock, LockFailed
 from ..remote import RemoteRepository, InvalidRPCMethod
 from ..remote import RemoteRepository, InvalidRPCMethod
 from ..repository import Repository, LoggedIO, TAG_COMMIT
 from ..repository import Repository, LoggedIO, TAG_COMMIT
 from . import BaseTestCase
 from . import BaseTestCase

+ 3 - 4
borg/upgrader.py

@@ -7,7 +7,7 @@ import shutil
 import time
 import time
 
 
 from .helpers import get_keys_dir, get_cache_dir, ProgressIndicatorPercent
 from .helpers import get_keys_dir, get_cache_dir, ProgressIndicatorPercent
-from .locking import UpgradableLock
+from .locking import Lock
 from .repository import Repository, MAGIC
 from .repository import Repository, MAGIC
 from .key import KeyfileKey, KeyfileNotFoundError
 from .key import KeyfileKey, KeyfileNotFoundError
 
 
@@ -39,7 +39,7 @@ class AtticRepositoryUpgrader(Repository):
                     shutil.copytree(self.path, backup, copy_function=os.link)
                     shutil.copytree(self.path, backup, copy_function=os.link)
             logger.info("opening attic repository with borg and converting")
             logger.info("opening attic repository with borg and converting")
             # now lock the repo, after we have made the copy
             # now lock the repo, after we have made the copy
-            self.lock = UpgradableLock(os.path.join(self.path, 'lock'), exclusive=True, timeout=1.0).acquire()
+            self.lock = Lock(os.path.join(self.path, 'lock'), exclusive=True, timeout=1.0).acquire()
             segments = [filename for i, filename in self.io.segment_iterator()]
             segments = [filename for i, filename in self.io.segment_iterator()]
             try:
             try:
                 keyfile = self.find_attic_keyfile()
                 keyfile = self.find_attic_keyfile()
@@ -48,8 +48,7 @@ class AtticRepositoryUpgrader(Repository):
             else:
             else:
                 self.convert_keyfiles(keyfile, dryrun)
                 self.convert_keyfiles(keyfile, dryrun)
         # partial open: just hold on to the lock
         # partial open: just hold on to the lock
-        self.lock = UpgradableLock(os.path.join(self.path, 'lock'),
-                                   exclusive=True).acquire()
+        self.lock = Lock(os.path.join(self.path, 'lock'), exclusive=True).acquire()
         try:
         try:
             self.convert_cache(dryrun)
             self.convert_cache(dryrun)
             self.convert_repo_index(dryrun=dryrun, inplace=inplace)
             self.convert_repo_index(dryrun=dryrun, inplace=inplace)