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