Rev 2625: Review feedback and documentation. in http://people.ubuntu.com/~robertc/baz2.0/repo-write-group

Robert Collins robertc at robertcollins.net
Wed Aug 1 01:20:41 BST 2007


At http://people.ubuntu.com/~robertc/baz2.0/repo-write-group

------------------------------------------------------------
revno: 2625
revision-id: robertc at robertcollins.net-20070801002037-cjf6ja1y3zzw5f2e
parent: robertc at robertcollins.net-20070731005340-g78eko5xn23lhpq3
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repo-write-group
timestamp: Wed 2007-08-01 10:20:37 +1000
message:
  Review feedback and documentation.
modified:
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/tests/repository_implementations/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
  doc/developers/repository.txt  repository.txt-20070709152006-xkhlek456eclha4u-1
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2007-07-31 00:52:11 +0000
+++ b/bzrlib/repository.py	2007-08-01 00:20:37 +0000
@@ -273,6 +273,10 @@
 
     def lock_write(self, token=None):
         """Lock this repository for writing.
+
+        This causes caching within the repository obejct to start accumlating
+        data during reads, and allows a 'write_group' to be obtained. Write
+        groups must be used for actual data insertion.
         
         :param token: if this is already locked, then lock_write will fail
             unless the token matches the existing lock.
@@ -281,6 +285,7 @@
             instance doesn't support using token locks.
         :raises MismatchedToken: if the specified token doesn't match the token
             of the existing lock.
+        :seealso: start_write_group.
 
         A token should be passed in if you know that you have locked the object
         some other way, and need to synchronise this object's state with that
@@ -482,6 +487,9 @@
 
         A write lock is required around the start_write_group/commit_write_group
         for the support of lock-requiring repository formats.
+
+        One can only insert data into a repository inside a write group.
+
         :return: None.
         """
         if not self.is_locked() or self.control_files._lock_mode != 'w':

=== modified file 'bzrlib/tests/repository_implementations/test_commit_builder.py'
--- a/bzrlib/tests/repository_implementations/test_commit_builder.py	2007-07-17 16:04:00 +0000
+++ b/bzrlib/tests/repository_implementations/test_commit_builder.py	2007-08-01 00:20:37 +0000
@@ -48,45 +48,50 @@
     def test_finish_inventory(self):
         tree = self.make_branch_and_tree(".")
         tree.lock_write()
-        builder = tree.branch.get_commit_builder([])
-        self.record_root(builder, tree)
-        builder.finish_inventory()
-        tree.branch.repository.commit_write_group()
-        tree.unlock()
+        try:
+            builder = tree.branch.get_commit_builder([])
+            self.record_root(builder, tree)
+            builder.finish_inventory()
+            tree.branch.repository.commit_write_group()
+        finally:
+            tree.unlock()
 
     def test_commit_message(self):
         tree = self.make_branch_and_tree(".")
         tree.lock_write()
-        builder = tree.branch.get_commit_builder([])
-        self.record_root(builder, tree)
-        builder.finish_inventory()
-        rev_id = builder.commit('foo bar blah')
-        tree.unlock()
+        try:
+            builder = tree.branch.get_commit_builder([])
+            self.record_root(builder, tree)
+            builder.finish_inventory()
+            rev_id = builder.commit('foo bar blah')
+        finally:
+            tree.unlock()
         rev = tree.branch.repository.get_revision(rev_id)
         self.assertEqual('foo bar blah', rev.message)
 
     def test_commit_with_revision_id(self):
         tree = self.make_branch_and_tree(".")
         tree.lock_write()
-        # use a unicode revision id to test more corner cases.
-        # The repository layer is meant to handle this.
-        revision_id = u'\xc8abc'.encode('utf8')
         try:
+            # use a unicode revision id to test more corner cases.
+            # The repository layer is meant to handle this.
+            revision_id = u'\xc8abc'.encode('utf8')
             try:
-                builder = tree.branch.get_commit_builder([],
-                    revision_id=revision_id)
-            except NonAsciiRevisionId:
-                revision_id = 'abc'
-                builder = tree.branch.get_commit_builder([],
-                    revision_id=revision_id)
-        except CannotSetRevisionId:
-            # This format doesn't support supplied revision ids
+                try:
+                    builder = tree.branch.get_commit_builder([],
+                        revision_id=revision_id)
+                except NonAsciiRevisionId:
+                    revision_id = 'abc'
+                    builder = tree.branch.get_commit_builder([],
+                        revision_id=revision_id)
+            except CannotSetRevisionId:
+                # This format doesn't support supplied revision ids
+                return
+            self.record_root(builder, tree)
+            builder.finish_inventory()
+            self.assertEqual(revision_id, builder.commit('foo bar'))
+        finally:
             tree.unlock()
-            return
-        self.record_root(builder, tree)
-        builder.finish_inventory()
-        self.assertEqual(revision_id, builder.commit('foo bar'))
-        tree.unlock()
         self.assertTrue(tree.branch.repository.has_revision(revision_id))
         # the revision id must be set on the inventory when saving it. This
         # does not precisely test that - a repository that wants to can add it
@@ -117,11 +122,13 @@
     def test_commit(self):
         tree = self.make_branch_and_tree(".")
         tree.lock_write()
-        builder = tree.branch.get_commit_builder([])
-        self.record_root(builder, tree)
-        builder.finish_inventory()
-        rev_id = builder.commit('foo bar')
-        tree.unlock()
+        try:
+            builder = tree.branch.get_commit_builder([])
+            self.record_root(builder, tree)
+            builder.finish_inventory()
+            rev_id = builder.commit('foo bar')
+        finally:
+            tree.unlock()
         self.assertNotEqual(None, rev_id)
         self.assertTrue(tree.branch.repository.has_revision(rev_id))
         # the revision id must be set on the inventory when saving it. This does not
@@ -132,11 +139,13 @@
     def test_revision_tree(self):
         tree = self.make_branch_and_tree(".")
         tree.lock_write()
-        builder = tree.branch.get_commit_builder([])
-        self.record_root(builder, tree)
-        builder.finish_inventory()
-        rev_id = builder.commit('foo bar')
-        tree.unlock()
+        try:
+            builder = tree.branch.get_commit_builder([])
+            self.record_root(builder, tree)
+            builder.finish_inventory()
+            rev_id = builder.commit('foo bar')
+        finally:
+            tree.unlock()
         rev_tree = builder.revision_tree()
         # Just a couple simple tests to ensure that it actually follows
         # the RevisionTree api.

=== modified file 'doc/developers/repository.txt'
--- a/doc/developers/repository.txt	2007-07-15 07:31:37 +0000
+++ b/doc/developers/repository.txt	2007-08-01 00:20:37 +0000
@@ -299,6 +299,53 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
+Caching and writeing of data
+============================
+
+Repositories try to provide a consistent view of the data within them
+within a 'lock context'. 
+
+Locks
+-----
+
+Locks come in two flavours - read locks and write locks. Read locks allow
+data to be read from the repository. Write locks allow data to be read and
+signal that you intend to write data at some point. The actual writing of
+data must take place within a Write Group.
+
+Write locks provide a cache of repository data during the period of the
+write lock, and allow write_groups to be acquired. For some repositories
+the presence of a write lock is exclusive to a single client, for others
+which are lock free or use server side locks (e.g.  svn), the write lock
+simply provides the cache context. 
+
+Write Groups
+------------
+
+Write groups are the only allowed means for inserting data into a
+repository.  These are created by ``start_write_group``, and concluded by
+either ``commit_write_group`` or ``abort_write_group``.  A write lock must
+be held on the repository for the entire duration.  At most one write
+group can be active on a repository at a time.
+
+Write groups signal to the repository the window during which data is
+actively being inserted. Several write groups could be committed during a
+single lock.
+
+There is no guarantee that data inserted during a write group will be
+invisible in the repository if the write group is not committed.
+Specifically repositories without atomic insertion facilities will be
+writing data as it is inserted within the write group, and may not be able
+to revert that data - e.g. in the event of a dropped SFTP connection in a
+knit repository, inserted file data will be visible in the repository. Some
+repositories have an atomic insertion facility, and for those
+all-or-nothing will apply.
+
+The precise meaning of a write group is format specific. For instance a
+knit based repository treats the write group methods as dummy calls,
+simply meeting the api that clients will use. A pack based repository will
+open a new pack container at the start of a write group, and rename it
+into place at commit time.
 
 
 ..



More information about the bazaar-commits mailing list