Rev 5201: (andrew) Allow repo.refresh_data() to be called in a write group for in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Tue May 4 12:16:20 BST 2010
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 5201 [merge]
revision-id: pqm at pqm.ubuntu.com-20100504111615-fcjkr4i0oi12oubc
parent: pqm at pqm.ubuntu.com-20100503090750-ojeefmuph3yj8m5z
parent: andrew.bennetts at canonical.com-20100504084752-lhksueg0uy5i25oa
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2010-05-04 12:16:15 +0100
message:
(andrew) Allow repo.refresh_data() to be called in a write group for
pack format repositories. (#574236)
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/repofmt/knitrepo.py knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/per_repository/test_refresh_data.py test_refresh_data.py-20090316045630-5sw0ipqwk7rvpn3h-1
=== modified file 'NEWS'
--- a/NEWS 2010-05-03 04:08:50 +0000
+++ b/NEWS 2010-05-04 02:41:17 +0000
@@ -96,6 +96,14 @@
implementations.
(Martin Pool)
+* ``Repository.refresh_data`` may now be called in a write group on
+ pack-based repositories. Older repositories will still raise an error
+ in this case. Subclasses of ``Repository`` can still override
+ ``Repository._refresh_data``, but are now responsible for raising
+ ``bzrlib.repository.IsInWriteGroupError`` if they do not support
+ ``refresh_data`` during a write group.
+ (Andrew Bennetts, #574236)
+
Internals
*********
=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py 2010-05-03 04:08:50 +0000
+++ b/bzrlib/remote.py 2010-05-04 08:47:52 +0000
@@ -1306,16 +1306,16 @@
return self._real_repository.make_working_trees()
def refresh_data(self):
- """Re-read any data needed to to synchronise with disk.
+ """Re-read any data needed to synchronise with disk.
This method is intended to be called after another repository instance
(such as one used by a smart server) has inserted data into the
- repository. It may not be called during a write group, but may be
- called at any other time.
+ repository. On all repositories this will work outside of write groups.
+ Some repository formats (pack and newer for bzrlib native formats)
+ support refresh_data inside write groups. If called inside a write
+ group on a repository that does not support refreshing in a write group
+ IsInWriteGroupError will be raised.
"""
- if self.is_in_write_group():
- raise errors.InternalBzrError(
- "May not refresh_data while in a write group.")
if self._real_repository is not None:
self._real_repository.refresh_data()
=== modified file 'bzrlib/repofmt/knitrepo.py'
--- a/bzrlib/repofmt/knitrepo.py 2010-04-26 13:51:08 +0000
+++ b/bzrlib/repofmt/knitrepo.py 2010-05-04 02:41:17 +0000
@@ -38,6 +38,7 @@
from bzrlib.decorators import needs_read_lock, needs_write_lock
from bzrlib.repository import (
CommitBuilder,
+ IsInWriteGroupError,
MetaDirRepository,
MetaDirRepositoryFormat,
RepositoryFormat,
@@ -210,6 +211,8 @@
def _refresh_data(self):
if not self.is_locked():
return
+ if self.is_in_write_group():
+ raise IsInWriteGroupError(self)
# Create a new transaction to force all knits to see the scope change.
# This is safe because we're outside a write group.
self.control_files._finish_transaction()
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py 2010-04-28 07:03:38 +0000
+++ b/bzrlib/repository.py 2010-05-04 08:47:52 +0000
@@ -26,7 +26,6 @@
chk_map,
config,
debug,
- errors,
fetch as _mod_fetch,
fifo_cache,
generate_ids,
@@ -62,7 +61,10 @@
entry_factory,
)
from bzrlib.lock import _RelockDebugMixin
-from bzrlib import registry
+from bzrlib import (
+ errors,
+ registry,
+ )
from bzrlib.trace import (
log_exception_quietly, note, mutter, mutter_callsite, warning)
@@ -71,6 +73,14 @@
_deprecation_warning_done = False
+class IsInWriteGroupError(errors.InternalBzrError):
+
+ _fmt = "May not refresh_data of repo %(repo)s while in a write group."
+
+ def __init__(self, repo):
+ errors.InternalBzrError.__init__(self, repo=repo)
+
+
class CommitBuilder(object):
"""Provides an interface to build up a commit.
@@ -1634,16 +1644,16 @@
return missing_keys
def refresh_data(self):
- """Re-read any data needed to to synchronise with disk.
+ """Re-read any data needed to synchronise with disk.
This method is intended to be called after another repository instance
(such as one used by a smart server) has inserted data into the
- repository. It may not be called during a write group, but may be
- called at any other time.
+ repository. On all repositories this will work outside of write groups.
+ Some repository formats (pack and newer for bzrlib native formats)
+ support refresh_data inside write groups. If called inside a write
+ group on a repository that does not support refreshing in a write group
+ IsInWriteGroupError will be raised.
"""
- if self.is_in_write_group():
- raise errors.InternalBzrError(
- "May not refresh_data while in a write group.")
self._refresh_data()
def resume_write_group(self, tokens):
=== modified file 'bzrlib/tests/per_repository/test_refresh_data.py'
--- a/bzrlib/tests/per_repository/test_refresh_data.py 2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/per_repository/test_refresh_data.py 2010-05-04 08:45:21 +0000
@@ -18,7 +18,7 @@
from bzrlib import (
errors,
- remote,
+ repository,
)
from bzrlib.tests import TestSkipped
from bzrlib.tests.per_repository import TestCaseWithRepository
@@ -45,22 +45,34 @@
self.addCleanup(repo.unlock)
repo.refresh_data()
- def test_refresh_data_in_write_group_errors(self):
+ def test_refresh_data_in_write_group(self):
+ # refresh_data may either succeed or raise IsInWriteGroupError during a
+ # write group.
repo = self.make_repository('.')
repo.lock_write()
self.addCleanup(repo.unlock)
repo.start_write_group()
self.addCleanup(repo.abort_write_group)
- # No flow control anticipated, BzrError is enough
- self.assertRaises(errors.BzrError, repo.refresh_data)
+ try:
+ repo.refresh_data()
+ except repository.IsInWriteGroupError:
+ # This is ok.
+ pass
+ else:
+ # This is ok too.
+ pass
- def test_refresh_data_after_fetch_new_data_visible(self):
- source = self.make_branch_and_tree('source')
- revid = source.commit('foo')
- repo = self.make_repository('target')
- token = repo.lock_write()
- self.addCleanup(repo.unlock)
+ def fetch_new_revision_into_concurrent_instance(self, repo, token):
+ """Create a new revision (revid 'new-rev') and fetch it into a
+ concurrent instance of repo.
+ """
+ source = self.make_branch_and_memory_tree('source')
+ source.lock_write()
+ self.addCleanup(source.unlock)
+ source.add([''], ['root-id'])
+ revid = source.commit('foo', rev_id='new-rev')
# Force data reading on weaves/knits
+ repo.all_revision_ids()
repo.revisions.keys()
repo.inventories.keys()
# server repo is the instance a smart server might hold for this
@@ -75,5 +87,34 @@
server_repo.fetch(source.branch.repository, revid)
finally:
server_repo.unlock()
+
+ def test_refresh_data_after_fetch_new_data_visible(self):
+ repo = self.make_repository('target')
+ token = repo.lock_write()
+ self.addCleanup(repo.unlock)
+ self.fetch_new_revision_into_concurrent_instance(repo, token)
repo.refresh_data()
- self.assertNotEqual({}, repo.get_graph().get_parent_map([revid]))
+ self.assertNotEqual({}, repo.get_graph().get_parent_map(['new-rev']))
+
+ def test_refresh_data_after_fetch_new_data_visible_in_write_group(self):
+ tree = self.make_branch_and_memory_tree('target')
+ tree.lock_write()
+ self.addCleanup(tree.unlock)
+ tree.add([''], ['root-id'])
+ tree.commit('foo', rev_id='commit-in-target')
+ repo = tree.branch.repository
+ token = repo.lock_write()
+ self.addCleanup(repo.unlock)
+ repo.start_write_group()
+ self.addCleanup(repo.abort_write_group)
+ self.fetch_new_revision_into_concurrent_instance(repo, token)
+ # Call refresh_data. It either fails with IsInWriteGroupError, or it
+ # succeeds and the new revisions are visible.
+ try:
+ repo.refresh_data()
+ except repository.IsInWriteGroupError:
+ pass
+ else:
+ self.assertEqual(
+ ['commit-in-target', 'new-rev'],
+ sorted(repo.all_revision_ids()))
More information about the bazaar-commits
mailing list