Rev 4728: (jam) Fix bug #507566 for correctness w/ concurrent autopacks in file:///home/pqm/archives/thelove/bzr/2.0/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Sun Jan 17 11:11:37 GMT 2010
At file:///home/pqm/archives/thelove/bzr/2.0/
------------------------------------------------------------
revno: 4728 [merge]
revision-id: pqm at pqm.ubuntu.com-20100117111134-5dg659dazkk6fr55
parent: pqm at pqm.ubuntu.com-20100115064904-nu4ys3eitcpgoux3
parent: john at arbash-meinel.com-20100116204603-556rlu1v6blzf2vk
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: 2.0
timestamp: Sun 2010-01-17 11:11:34 +0000
message:
(jam) Fix bug #507566 for correctness w/ concurrent autopacks
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/repofmt/pack_repo.py pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
=== modified file 'NEWS'
--- a/NEWS 2010-01-15 03:34:28 +0000
+++ b/NEWS 2010-01-17 11:11:34 +0000
@@ -38,6 +38,11 @@
returns ``EINTR`` by calling ``PyErr_CheckSignals``. This affected the
optional ``_readdir_pyx`` extension. (Andrew Bennetts, #495023)
+* Concurrent autopacks will no longer lose a newly created pack file.
+ There was a race condition, where if the reload happened at the right
+ time, the second packer would forget the name of the newly added pack
+ file. (John Arbash Meinel, Gareth White, #507566)
+
* Give a clearer message if the lockdir disappears after being apparently
successfully taken. (Martin Pool, #498378)
=== modified file 'bzrlib/repofmt/pack_repo.py'
--- a/bzrlib/repofmt/pack_repo.py 2009-09-09 18:52:56 +0000
+++ b/bzrlib/repofmt/pack_repo.py 2010-01-16 20:46:03 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
+# Copyright (C) 2007-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -1987,8 +1987,13 @@
if first_read:
return True
# out the new value.
- disk_nodes, _, _ = self._diff_pack_names()
- self._packs_at_load = disk_nodes
+ disk_nodes, deleted_nodes, new_nodes = self._diff_pack_names()
+ # _packs_at_load is meant to be the explicit list of names in
+ # 'pack-names' at then start. As such, it should not contain any
+ # pending names that haven't been written out yet.
+ pack_names_nodes = disk_nodes.difference(new_nodes)
+ pack_names_nodes.update(deleted_nodes)
+ self._packs_at_load = pack_names_nodes
(removed, added,
modified) = self._syncronize_pack_names_from_disk_nodes(disk_nodes)
if removed or added or modified:
=== modified file 'bzrlib/tests/test_repository.py'
--- a/bzrlib/tests/test_repository.py 2009-09-09 01:58:47 +0000
+++ b/bzrlib/tests/test_repository.py 2010-01-16 20:46:03 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd
+# Copyright (C) 2006-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -62,6 +62,7 @@
revision as _mod_revision,
symbol_versioning,
upgrade,
+ versionedfile,
workingtree,
)
from bzrlib.repofmt import (
@@ -1279,6 +1280,45 @@
self.assertEqual({revs[-1]:(revs[-2],)}, r.get_parent_map([revs[-1]]))
self.assertFalse(packs.reload_pack_names())
+ def test_reload_pack_names_preserves_pending(self):
+ # TODO: Update this to also test for pending-deleted names
+ tree, r, packs, revs = self.make_packs_and_alt_repo(write_lock=True)
+ # We will add one pack (via start_write_group + insert_record_stream),
+ # and remove another pack (via _remove_pack_from_memory)
+ orig_names = packs.names()
+ orig_at_load = packs._packs_at_load
+ to_remove_name = iter(orig_names).next()
+ r.start_write_group()
+ self.addCleanup(r.abort_write_group)
+ r.texts.insert_record_stream([versionedfile.FulltextContentFactory(
+ ('text', 'rev'), (), None, 'content\n')])
+ new_pack = packs._new_pack
+ self.assertTrue(new_pack.data_inserted())
+ new_pack.finish()
+ packs.allocate(new_pack)
+ packs._new_pack = None
+ removed_pack = packs.get_pack_by_name(to_remove_name)
+ packs._remove_pack_from_memory(removed_pack)
+ names = packs.names()
+ all_nodes, deleted_nodes, new_nodes = packs._diff_pack_names()
+ new_names = set([x[0][0] for x in new_nodes])
+ self.assertEqual(names, sorted([x[0][0] for x in all_nodes]))
+ self.assertEqual(set(names) - set(orig_names), new_names)
+ self.assertEqual(set([new_pack.name]), new_names)
+ self.assertEqual([to_remove_name],
+ sorted([x[0][0] for x in deleted_nodes]))
+ packs.reload_pack_names()
+ reloaded_names = packs.names()
+ self.assertEqual(orig_at_load, packs._packs_at_load)
+ self.assertEqual(names, reloaded_names)
+ all_nodes, deleted_nodes, new_nodes = packs._diff_pack_names()
+ new_names = set([x[0][0] for x in new_nodes])
+ self.assertEqual(names, sorted([x[0][0] for x in all_nodes]))
+ self.assertEqual(set(names) - set(orig_names), new_names)
+ self.assertEqual(set([new_pack.name]), new_names)
+ self.assertEqual([to_remove_name],
+ sorted([x[0][0] for x in deleted_nodes]))
+
def test_autopack_reloads_and_stops(self):
tree, r, packs, revs = self.make_packs_and_alt_repo(write_lock=True)
# After we have determined what needs to be autopacked, trigger a
More information about the bazaar-commits
mailing list