Rev 5764: Implement a LockableConfigObjStore to be able to mimick the actual behaviour. in file:///home/vila/src/bzr/experimental/config/

Vincent Ladeuil v.ladeuil+lp at free.fr
Wed Apr 6 17:31:11 UTC 2011


At file:///home/vila/src/bzr/experimental/config/

------------------------------------------------------------
revno: 5764
revision-id: v.ladeuil+lp at free.fr-20110406173110-6aezj2dnr9q8bvwm
parent: v.ladeuil+lp at free.fr-20110406162909-q5fqc50dlegc10km
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: config-abstract-store
timestamp: Wed 2011-04-06 19:31:10 +0200
message:
  Implement a LockableConfigObjStore to be able to mimick the actual behaviour.
-------------- next part --------------
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py	2011-04-06 16:15:18 +0000
+++ b/bzrlib/config.py	2011-04-06 17:31:10 +0000
@@ -848,7 +848,7 @@
         # LockableConfig for other kind of transports, we will need to reuse
         # whatever connection is already established -- vila 20100929
         self.transport = transport.get_transport(self.dir)
-        self._lock = lockdir.LockDir(self.transport, 'lock')
+        self._lock = lockdir.LockDir(self.transport, self.lock_name)
 
     def _create_from_string(self, unicode_bytes, save):
         super(LockableConfig, self)._create_from_string(unicode_bytes, False)
@@ -2152,6 +2152,44 @@
         return MutableSection(section_name, section)
 
 
+class LockableConfigObjStore(ConfigObjStore):
+    """A ConfigObjStore using locks on save to ensure store integrity."""
+
+    def __init__(self, transport, file_name, lock_dir_name=None):
+        """A config Store using ConfigObj for storage.
+
+        :param transport: The transport object where the config file is located.
+
+        :param file_name: The config file basename in the transport directory.
+        """
+        if lock_dir_name is None:
+            lock_dir_name = 'lock'
+        self.lock_dir_name = lock_dir_name
+        super(LockableConfigObjStore, self).__init__(transport, file_name)
+        self._lock = lockdir.LockDir(self.transport, self.lock_dir_name)
+
+    def lock_write(self, token=None):
+        """Takes a write lock in the directory containing the config file.
+
+        If the directory doesn't exist it is created.
+        """
+        # FIXME: This doesn't check the ownership of the created directories as
+        # ensure_config_dir_exists does. It should if the transport is local
+        # -- vila 2011-04-06
+        self.transport.create_prefix()
+        return self._lock.lock_write(token)
+
+    def unlock(self):
+        self._lock.unlock()
+
+    def break_lock(self):
+        self._lock.break_lock()
+
+    @needs_write_lock
+    def save(self):
+        super(LockableConfigObjStore, self).save()
+
+
 class cmd_config(commands.Command):
     __doc__ = """Display, set or remove a configuration option.
 

=== modified file 'bzrlib/tests/test_config.py'
--- a/bzrlib/tests/test_config.py	2011-04-06 16:29:09 +0000
+++ b/bzrlib/tests/test_config.py	2011-04-06 17:31:10 +0000
@@ -831,7 +831,7 @@
         def c1_write_config_file():
             before_writing.set()
             c1_orig()
-            # The lock is held we wait for the main thread to decide when to
+            # The lock is held. We wait for the main thread to decide when to
             # continue
             after_writing.wait()
         c1._write_config_file = c1_write_config_file
@@ -864,7 +864,7 @@
        c1_orig = c1._write_config_file
        def c1_write_config_file():
            ready_to_write.set()
-           # The lock is held we wait for the main thread to decide when to
+           # The lock is held. We wait for the main thread to decide when to
            # continue
            do_writing.wait()
            c1_orig()
@@ -2066,6 +2066,19 @@
             sections[3])
 
 
+class TestLockableConfigObjStore(TestStore):
+
+    def test_create_store_in_created_dir(self):
+        t = self.get_transport('dir/subdir')
+        store = config.LockableConfigObjStore(t, 'foo.conf')
+        store.get_mutable_section(None).set('foo', 'bar')
+        store.save()
+
+    # FIXME: We should adapt the tests in TestLockableConfig about concurrent
+    # writes, for now, I'll just rely on using the same code (copied, but
+    # pretty trivial) -- vila 20110-04-06
+
+
 class TestConfigGetOptions(tests.TestCaseWithTransport, TestOptionsMixin):
 
     def setUp(self):



More information about the bazaar-commits mailing list