Merge lp:~vila/bzr/config-lock-branch into lp:bzr

Proposed by Vincent Ladeuil
Status: Merged
Approved by: Vincent Ladeuil
Approved revision: no longer in the source branch.
Merged at revision: 5942
Proposed branch: lp:~vila/bzr/config-lock-branch
Merge into: lp:bzr
Prerequisite: lp:~vila/bzr/config-locks
Diff against target: 90 lines (+29/-8)
2 files modified
bzrlib/config.py (+19/-4)
bzrlib/tests/test_config.py (+10/-4)
To merge this branch: bzr merge lp:~vila/bzr/config-lock-branch
Reviewer Review Type Date Requested Status
Andrew Bennetts Needs Fixing
Review via email: mp+61466@code.launchpad.net

Commit message

Implement branch config locking.

Description of the change

This properly implements BranchStore locking by delegating to the associated Branch object.

Note that it takes care of not creating a ref cycle. This is not triggered today but I prefer to handle it now that I realise it.

I remove some assertions in the tests that were peaking under the covers about the lock implementation but didn't provide more checks.

To post a comment you must log in.
Revision history for this message
Andrew Bennetts (spiv) wrote :

This appears to be in a broken state:

29 + self.branch = weakref.ref(branch)
30 +
31 + def lock_write(self, token=None):
32 + return self.branch.lock_write(token)

Surely that has to be “self.branch().lock_write(token)”? Does this branch pass tests?

review: Needs Fixing
Revision history for this message
Vincent Ladeuil (vila) wrote :

Bah, of course not (looks like I switched at the wrong time between my loom threads), already fixed in lp:~vila/bzr/config-lock-remote, but I will fix this one by not using a weakref here.

Revision history for this message
Vincent Ladeuil (vila) wrote :

ping, review comments addressed, next review eagerly wanted ;)

Revision history for this message
Vincent Ladeuil (vila) wrote :

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/config.py'
2--- bzrlib/config.py 2011-05-31 08:16:36 +0000
3+++ bzrlib/config.py 2011-05-31 08:16:36 +0000
4@@ -65,6 +65,7 @@
5 import os
6 import string
7 import sys
8+import weakref
9
10 from bzrlib import commands
11 from bzrlib.decorators import needs_write_lock
12@@ -2364,14 +2365,28 @@
13 super(LocationStore, self).__init__(t, 'locations.conf')
14
15
16-# FIXME: We should rely on the branch itself to be locked (possibly checking
17-# that even) but we shouldn't lock ourselves. This may make `bzr config` is
18-# a bit trickier though but I punt for now -- vila 20110512
19-class BranchStore(LockableIniFileStore):
20+class BranchStore(IniFileStore):
21
22 def __init__(self, branch):
23 super(BranchStore, self).__init__(branch.control_transport,
24 'branch.conf')
25+ # FIXME: This creates a cycle -- vila 2011-05-27
26+ self.branch = branch
27+
28+ def lock_write(self, token=None):
29+ return self.branch.lock_write(token)
30+
31+ def unlock(self):
32+ return self.branch.unlock()
33+
34+ @needs_write_lock
35+ def save(self):
36+ # We need to be able to override the undecorated implementation
37+ self.save_without_locking()
38+
39+ def save_without_locking(self):
40+ super(BranchStore, self).save()
41+
42
43 class SectionMatcher(object):
44 """Select sections into a given Store.
45
46=== modified file 'bzrlib/tests/test_config.py'
47--- bzrlib/tests/test_config.py 2011-05-31 08:16:36 +0000
48+++ bzrlib/tests/test_config.py 2011-05-31 08:16:36 +0000
49@@ -75,7 +75,11 @@
50 def build_branch_store(test):
51 if getattr(test, 'branch', None) is None:
52 test.branch = test.make_branch('branch')
53- return config.BranchStore(test.branch)
54+ # Since we can be called to create different stores, we need to build them
55+ # from different branch *objects*, even if they point to the same branch on
56+ # disk, otherwise tests about conccurent updates won't be able to trigger
57+ # LockContention
58+ return config.BranchStore(branch.Branch.open('branch'))
59 config.test_store_builder_registry.register('branch', build_branch_store)
60
61
62@@ -87,7 +91,11 @@
63 def build_branch_stack(test):
64 if getattr(test, 'branch', None) is None:
65 test.branch = test.make_branch('branch')
66- return config.BranchStack(test.branch)
67+ # Since we can be called to create different stacks, we need to build them
68+ # from different branch *objects*, even if they point to the same branch on
69+ # disk, otherwise tests about conccurent updates won't be able to trigger
70+ # LockContention
71+ return config.BranchStack(branch.Branch.open('branch'))
72 config.test_stack_builder_registry.register('branch', build_branch_stack)
73
74
75@@ -2180,7 +2188,6 @@
76 self.addCleanup(after_writing.set)
77 t1.start()
78 before_writing.wait()
79- self.assertTrue(c1.store._lock.is_held)
80 self.assertRaises(errors.LockContention,
81 c2.set, 'one', 'c2')
82 self.assertEquals('c1', c1.get('one'))
83@@ -2216,7 +2223,6 @@
84 t1.start()
85 # Ensure the thread is ready to write
86 ready_to_write.wait()
87- self.assertTrue(c1.store._lock.is_held)
88 self.assertEquals('c1', c1.get('one'))
89 # If we read during the write, we get the old value
90 c2 = self.get_stack(self)