branch locking mk2.

Nir Soffer nirs at freeshell.org
Wed Feb 8 12:11:21 GMT 2006


On 8 Feb, 2006, at 12:14, Jan Hudec wrote:

> On Wed, Feb 08, 2006 at 11:16:05 +0200, Nir Soffer wrote:
>> I'm not sure how your solution works, so I'll describe how moin
>> exclusive lock works, and some use issues.
>>
>> Moin exclusive lock acquire a lock by creating a directory at a path,
>> and release the lock by removing the directory.
>>
>> If the directory already exists, it goes into loop of trying to expire
>> the other lock (that created the directory) and create the directory
>> again, until the acquire timeout is reached, then it returns False.
>
> Which fails over the network. Because over a network, it is possible to
> get an error back even if you actually created the directory. So you
> need a way to find out what actually happened on the server ex-post.
> Therefore you must somehow mark the directory. Which can be done by
> creating something inside it. But You can't do that atomically. So you
> must do that beforehand.

What do you mean by over a network? moin locks are used by multiple 
process on one machine.

>
>> Expiring a lock is based on the modification time of the directory and
>> the timeout lock instance variable.
>>
>> The write lock is a subclass that also try to remove read locks while
>> acquiring, which have smaller timeout.
>>
>> Example usage:
>> 	
>> 	lock = WriteLock('/tmp/resource/lock', timeout=60)
>>
>> 	if lock.acquire(10):
>> 		try:
>> 			# change the resource
>> 		finally:
>> 			lock.release()
>>
>> If somehow you are left with a unused lock, the above lock will expire
>> only after 60 seconds. Killing a process is safe (I'm not sure kill -9
>> is).
>
> No, it's not. It can't be for any lock not implemented by kernel 
> itself.
> Because when process gets SIGKILL, it is simply deleted, whithout a
> chance to run even a single instruction. So it can't clean up anything,
> except things cleaned up by kernel.

Sure, its hard to promise anything when others kill you. This system 
require cleanup after you kill it, or you may block for full timeout by 
a orphaned lock in the worst case.

>
>> The design is little broken because you must create all locks for same
>> path with the same timeout. It can  be solved by creating the lock on
>> the resource, then return a shared lock. Many clients can reference
>> the same lock instance, only one of them can acquire the lock at a
>> time.
>>
>> 	lock = branch.shared_lock() # return a lock using the branch timeout
>>
>> The resource lock timeout must be shared between different processes
>> that try to acquire a lock on the same resource, and must not change
>> while the resource is locked.
>
> Except it will change.
>
> Actually it is important to note that the lock does not actually lock
> anything! It is rather something like 'Please, please, wait a little
> until I finish what I am doing' -- any other client *can* break your
> lock anytime and it still must not result in a corrupted branch.

I don't see how you can change the timeout after a caller got a lock. 
The caller can safely assume he has a lock for the full timeout.


Best Regards,

Nir Soffer





More information about the bazaar mailing list