[MERGE] Add an optional 'token' keyword argument to LockableFiles.lock_write
Martin Pool
mbp at canonical.com
Mon Feb 12 05:33:25 GMT 2007
On 12 Feb 2007, Andrew Bennetts <andrew at canonical.com> wrote:
> +class TokenMismatch(LockError):
> +
> + _fmt = "The lock token %(given_token)r does not match lock token %(lock_token)r."
> +
> + internal_error = True
> +
> + def __init__(self, given_token, lock_token):
> + self.given_token = given_token
> + self.lock_token = lock_token
> +
> +
> class PointlessCommit(BzrError):
I think you can be more clear here and in the other docstrings about
what has happened in this case: does it mean that someone else broke the
lock between when you got the initial token and when you tried to
continue the lock?
> _fmt = "No changes to commit"
>
> === modified file bzrlib/lockable_files.py
> --- bzrlib/lockable_files.py
> +++ bzrlib/lockable_files.py
> @@ -212,21 +212,33 @@
> raise errors.BzrBadParameterNotString(a_string)
> self.put(path, StringIO(a_string.encode('utf-8')))
>
> - def lock_write(self):
> + def lock_write(self, token=None):
> + """Lock this group of files for writing.
> +
> + :param token: if this is already locked, then lock_write will fail
> + unless the token matches the existing lock.
> + :returns: a token if this instance supports tokens, otherwise None.
> + :raises TokenLockingNotSupported: when a token is given but this
> + instance doesn't support using token locks.
> + :raises MismatchedToken: if the specified token doesn't match the token
> + of the existing lock.
> + """
Could do with a couple of sentences about why you might want to pass the
token and where it comes from.
I note in passing that having to pass this through seems like additional
reason to remove LockableFiles and just talk to either the transport or
the lock directly.
> @@ -457,3 +479,14 @@
> 'locked %s' % (format_delta(delta),),
> ]
>
> + def validate_token(self, token):
> + if token is not None:
> + info = self.peek()
> + if info is None:
> + # Lock isn't held
> + lock_token = None
> + else:
> + lock_token = info.get('nonce')
> + if token != lock_token:
> + raise errors.TokenMismatch(token, lock_token)
> +
Why not use the whole info object as the token? Doing so makes it a
little more sure we won't collide and might help debug any problems.
--
Martin
More information about the bazaar
mailing list