فهرست منبع

locking: better differentiate new vs. old clients, lock upgrade for replay

old clients use self.exclusive = None and do a read->write lock upgrade when needed.
new clients use self.exclusive = True/False and never upgrade.

replay fakes an old client by setting self.exclusive = None to get a lock upgrade if needed.
Thomas Waldmann 8 سال پیش
والد
کامیت
33e3348208
2فایلهای تغییر یافته به همراه6 افزوده شده و 2 حذف شده
  1. 1 1
      borg/remote.py
  2. 5 1
      borg/repository.py

+ 1 - 1
borg/remote.py

@@ -114,7 +114,7 @@ class RepositoryServer:  # pragma: no cover
     def negotiate(self, versions):
     def negotiate(self, versions):
         return RPC_PROTOCOL_VERSION
         return RPC_PROTOCOL_VERSION
 
 
-    def open(self, path, create=False, lock_wait=None, lock=True, exclusive=False, append_only=False):
+    def open(self, path, create=False, lock_wait=None, lock=True, exclusive=None, append_only=False):
         path = os.fsdecode(path)
         path = os.fsdecode(path)
         if path.startswith('/~'):
         if path.startswith('/~'):
             path = path[1:]
             path = path[1:]

+ 5 - 1
borg/repository.py

@@ -79,7 +79,7 @@ class Repository:
         if self.do_create:
         if self.do_create:
             self.do_create = False
             self.do_create = False
             self.create(self.path)
             self.create(self.path)
-        self.open(self.path, self.exclusive, lock_wait=self.lock_wait, lock=self.do_lock)
+        self.open(self.path, bool(self.exclusive), lock_wait=self.lock_wait, lock=self.do_lock)
         return self
         return self
 
 
     def __exit__(self, exc_type, exc_val, exc_tb):
     def __exit__(self, exc_type, exc_val, exc_tb):
@@ -317,6 +317,9 @@ class Repository:
         self.compact = set()
         self.compact = set()
 
 
     def replay_segments(self, index_transaction_id, segments_transaction_id):
     def replay_segments(self, index_transaction_id, segments_transaction_id):
+        # fake an old client, so that in case we do not have an exclusive lock yet, prepare_txn will upgrade the lock:
+        remember_exclusive = self.exclusive
+        self.exclusive = None
         self.prepare_txn(index_transaction_id, do_cleanup=False)
         self.prepare_txn(index_transaction_id, do_cleanup=False)
         try:
         try:
             segment_count = sum(1 for _ in self.io.segment_iterator())
             segment_count = sum(1 for _ in self.io.segment_iterator())
@@ -332,6 +335,7 @@ class Repository:
             pi.finish()
             pi.finish()
             self.write_index()
             self.write_index()
         finally:
         finally:
+            self.exclusive = remember_exclusive
             self.rollback()
             self.rollback()
 
 
     def _update_index(self, segment, objects, report=None):
     def _update_index(self, segment, objects, report=None):