Rev 3811: KnitVersionedFile.annotate() now retries when appropriate. in http://bzr.arbash-meinel.com/branches/bzr/1.9-dev/pack_retry_153786

John Arbash Meinel john at arbash-meinel.com
Sat Oct 25 03:37:42 BST 2008


At http://bzr.arbash-meinel.com/branches/bzr/1.9-dev/pack_retry_153786

------------------------------------------------------------
revno: 3811
revision-id: john at arbash-meinel.com-20081025023735-bsht1lfu6jye6z7o
parent: john at arbash-meinel.com-20081025022225-wbds6xl8t5ptod6p
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: pack_retry_153786
timestamp: Fri 2008-10-24 21:37:35 -0500
message:
  KnitVersionedFile.annotate() now retries when appropriate.
  
  As near as I can tell, this is the last code that works in terms of records,
  which is the last place that requires the indexes and packs to stay in perfect
  sync.
-------------- next part --------------
=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py	2008-10-25 02:22:25 +0000
+++ b/bzrlib/knit.py	2008-10-25 02:37:35 +0000
@@ -1451,9 +1451,6 @@
 
         :return: An iterator over (line, key).
         """
-        # TODO: We want to build in retrying, because we only hold the
-        #       'records' for the duration of this function, outside of this
-        #       function we deal in 'keys'.
         if pb is None:
             pb = progress.DummyProgress()
         keys = set(keys)
@@ -2818,14 +2815,17 @@
         if len(self._knit._fallback_vfs) > 0:
             # stacked knits can't use the fast path at present.
             return self._simple_annotate(key)
-        # TODO: We want to create retry logic at this level, between
-        #       _get_build_graph and _annotate_records, since that is the level
-        #       that we talk in terms of 'records' and not in terms of keys
-        records = self._get_build_graph(key)
-        if key in self._ghosts:
-            raise errors.RevisionNotPresent(key, self._knit)
-        self._annotate_records(records)
-        return self._annotated_lines[key]
+        while True:
+            try:
+                records = self._get_build_graph(key)
+                if key in self._ghosts:
+                    raise errors.RevisionNotPresent(key, self._knit)
+                self._annotate_records(records)
+                return self._annotated_lines[key]
+            except errors.RetryWithNewPacks, e:
+                self._knit._access.reload_or_raise(e)
+                # The cached build_details are no longer valid
+                self._all_build_details.clear()
 
     def _simple_annotate(self, key):
         """Return annotated fulltext, rediffing from the full texts.

=== modified file 'bzrlib/tests/test_knit.py'
--- a/bzrlib/tests/test_knit.py	2008-10-25 02:22:25 +0000
+++ b/bzrlib/tests/test_knit.py	2008-10-25 02:37:35 +0000
@@ -584,6 +584,24 @@
         access.reload_or_raise(retry_exc)
         self.assertEqual([2], reload_called)
 
+    def test_annotate_retries(self):
+        vf, reload_counter = self.make_vf_for_retrying()
+        # It is a little bit bogus to annotate the Revision VF, but it works,
+        # as we have ancestry stored there
+        key = ('rev-3',)
+        reload_lines = vf.annotate(key)
+        self.assertEqual([1, 1, 0], reload_counter)
+        plain_lines = vf.annotate(key)
+        self.assertEqual([1, 1, 0], reload_counter) # No extra reloading
+        if reload_lines != plain_lines:
+            self.fail('Annotation was not identical with reloading.')
+        # Now delete the packs-in-use, which should trigger another reload, but
+        # this time we just raise an exception because we can't recover
+        for trans, name in vf._access._indices.itervalues():
+            trans.delete(name)
+        self.assertRaises(errors.NoSuchFile, vf.annotate, key)
+        self.assertEqual([2, 1, 1], reload_counter)
+
     def test__get_record_map_retries(self):
         vf, reload_counter = self.make_vf_for_retrying()
         keys = [('rev-1',), ('rev-2',), ('rev-3',)]



More information about the bazaar-commits mailing list