branch locking mk2.

Nir Soffer nirs at freeshell.org
Wed Feb 8 09:16:05 GMT 2006


On 8 Feb, 2006, at 3:25, Robert Collins wrote:

> Perhaps you could describe the differences between moins approach and
> what I described ?

moin lock is based only on creating a directory, and does not assume 
anything on rename, which is not atomic on Windows:

	"On Windows, if dst already exists, OSError will be raised even if it 
is a file; there may be no way to implement an atomic rename when dst 
names an existing file."
	-- http://docs.python.org/lib/os-file-dir.html

I'm not sure if this effect the solution you described, but its a 
common error for posix users :-)

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.

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).

It can be better to save information about the process holding the lock 
in the lock directory, but its not easy,  because you can't create a 
directory with a file atomically in a portable way.

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.


Best Regards,

Nir Soffer





More information about the bazaar mailing list