Merge lp:~jameinel/bzr/2.0.4-autopack-507566 into lp:bzr/2.0

Proposed by John A Meinel
Status: Merged
Merged at revision: not available
Proposed branch: lp:~jameinel/bzr/2.0.4-autopack-507566
Merge into: lp:bzr/2.0
Diff against target: 105 lines (+54/-4)
3 files modified
NEWS (+5/-0)
bzrlib/repofmt/pack_repo.py (+8/-3)
bzrlib/tests/test_repository.py (+41/-1)
To merge this branch: bzr merge lp:~jameinel/bzr/2.0.4-autopack-507566
Reviewer Review Type Date Requested Status
Robert Collins (community) Approve
Review via email: mp+17523@code.launchpad.net
To post a comment you must log in.
Revision history for this message
John A Meinel (jameinel) wrote :

This is a bugfix for the 'critical' bug #507566. It seems that if you had concurrent autopacking, the second one would restart, but 'forget' that it had a new pack which needed to be added.

This seems localized enough that it is worth fixing in the 2.0 series.

Revision history for this message
Robert Collins (lifeless) wrote :

 review: +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'NEWS'
--- NEWS 2010-01-15 03:34:28 +0000
+++ NEWS 2010-01-16 20:52:12 +0000
@@ -38,6 +38,11 @@
38 returns ``EINTR`` by calling ``PyErr_CheckSignals``. This affected the38 returns ``EINTR`` by calling ``PyErr_CheckSignals``. This affected the
39 optional ``_readdir_pyx`` extension. (Andrew Bennetts, #495023)39 optional ``_readdir_pyx`` extension. (Andrew Bennetts, #495023)
4040
41* Concurrent autopacks will no longer lose a newly created pack file.
42 There was a race condition, where if the reload happened at the right
43 time, the second packer would forget the name of the newly added pack
44 file. (John Arbash Meinel, Gareth White, #507566)
45
41* Give a clearer message if the lockdir disappears after being apparently46* Give a clearer message if the lockdir disappears after being apparently
42 successfully taken. (Martin Pool, #498378)47 successfully taken. (Martin Pool, #498378)
4348
4449
=== modified file 'bzrlib/repofmt/pack_repo.py'
--- bzrlib/repofmt/pack_repo.py 2009-09-09 18:52:56 +0000
+++ bzrlib/repofmt/pack_repo.py 2010-01-16 20:52:12 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd1# Copyright (C) 2007-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -1987,8 +1987,13 @@
1987 if first_read:1987 if first_read:
1988 return True1988 return True
1989 # out the new value.1989 # out the new value.
1990 disk_nodes, _, _ = self._diff_pack_names()1990 disk_nodes, deleted_nodes, new_nodes = self._diff_pack_names()
1991 self._packs_at_load = disk_nodes1991 # _packs_at_load is meant to be the explicit list of names in
1992 # 'pack-names' at then start. As such, it should not contain any
1993 # pending names that haven't been written out yet.
1994 pack_names_nodes = disk_nodes.difference(new_nodes)
1995 pack_names_nodes.update(deleted_nodes)
1996 self._packs_at_load = pack_names_nodes
1992 (removed, added,1997 (removed, added,
1993 modified) = self._syncronize_pack_names_from_disk_nodes(disk_nodes)1998 modified) = self._syncronize_pack_names_from_disk_nodes(disk_nodes)
1994 if removed or added or modified:1999 if removed or added or modified:
19952000
=== modified file 'bzrlib/tests/test_repository.py'
--- bzrlib/tests/test_repository.py 2009-09-09 01:58:47 +0000
+++ bzrlib/tests/test_repository.py 2010-01-16 20:52:12 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd1# Copyright (C) 2006-2010 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -62,6 +62,7 @@
62 revision as _mod_revision,62 revision as _mod_revision,
63 symbol_versioning,63 symbol_versioning,
64 upgrade,64 upgrade,
65 versionedfile,
65 workingtree,66 workingtree,
66 )67 )
67from bzrlib.repofmt import (68from bzrlib.repofmt import (
@@ -1279,6 +1280,45 @@
1279 self.assertEqual({revs[-1]:(revs[-2],)}, r.get_parent_map([revs[-1]]))1280 self.assertEqual({revs[-1]:(revs[-2],)}, r.get_parent_map([revs[-1]]))
1280 self.assertFalse(packs.reload_pack_names())1281 self.assertFalse(packs.reload_pack_names())
12811282
1283 def test_reload_pack_names_preserves_pending(self):
1284 # TODO: Update this to also test for pending-deleted names
1285 tree, r, packs, revs = self.make_packs_and_alt_repo(write_lock=True)
1286 # We will add one pack (via start_write_group + insert_record_stream),
1287 # and remove another pack (via _remove_pack_from_memory)
1288 orig_names = packs.names()
1289 orig_at_load = packs._packs_at_load
1290 to_remove_name = iter(orig_names).next()
1291 r.start_write_group()
1292 self.addCleanup(r.abort_write_group)
1293 r.texts.insert_record_stream([versionedfile.FulltextContentFactory(
1294 ('text', 'rev'), (), None, 'content\n')])
1295 new_pack = packs._new_pack
1296 self.assertTrue(new_pack.data_inserted())
1297 new_pack.finish()
1298 packs.allocate(new_pack)
1299 packs._new_pack = None
1300 removed_pack = packs.get_pack_by_name(to_remove_name)
1301 packs._remove_pack_from_memory(removed_pack)
1302 names = packs.names()
1303 all_nodes, deleted_nodes, new_nodes = packs._diff_pack_names()
1304 new_names = set([x[0][0] for x in new_nodes])
1305 self.assertEqual(names, sorted([x[0][0] for x in all_nodes]))
1306 self.assertEqual(set(names) - set(orig_names), new_names)
1307 self.assertEqual(set([new_pack.name]), new_names)
1308 self.assertEqual([to_remove_name],
1309 sorted([x[0][0] for x in deleted_nodes]))
1310 packs.reload_pack_names()
1311 reloaded_names = packs.names()
1312 self.assertEqual(orig_at_load, packs._packs_at_load)
1313 self.assertEqual(names, reloaded_names)
1314 all_nodes, deleted_nodes, new_nodes = packs._diff_pack_names()
1315 new_names = set([x[0][0] for x in new_nodes])
1316 self.assertEqual(names, sorted([x[0][0] for x in all_nodes]))
1317 self.assertEqual(set(names) - set(orig_names), new_names)
1318 self.assertEqual(set([new_pack.name]), new_names)
1319 self.assertEqual([to_remove_name],
1320 sorted([x[0][0] for x in deleted_nodes]))
1321
1282 def test_autopack_reloads_and_stops(self):1322 def test_autopack_reloads_and_stops(self):
1283 tree, r, packs, revs = self.make_packs_and_alt_repo(write_lock=True)1323 tree, r, packs, revs = self.make_packs_and_alt_repo(write_lock=True)
1284 # After we have determined what needs to be autopacked, trigger a1324 # After we have determined what needs to be autopacked, trigger a

Subscribers

People subscribed via source and target branches