Several changes to DB implementation.
1. Database stores a file version, so we can add to it in the future. 2. Database indexed by hashes and not numerical indexes. 3. Specs built by database have consistent hashes and it's checked. 4. minor naming and whitespace changes.
This commit is contained in:
@@ -222,7 +222,7 @@ def working_dir(dirname, **kwargs):
|
||||
|
||||
def touch(path):
|
||||
"""Creates an empty file at the specified path."""
|
||||
with closing(open(path, 'a')) as file:
|
||||
with open(path, 'a') as file:
|
||||
os.utime(path, None)
|
||||
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
##############################################################################
|
||||
"""Lock implementation for shared filesystems."""
|
||||
import os
|
||||
import fcntl
|
||||
import errno
|
||||
@@ -34,11 +35,13 @@ class Read_Lock_Instance(object):
|
||||
A context manager for getting shared access to the object lock
|
||||
Arguments are lock and timeout (default 5 minutes)
|
||||
"""
|
||||
def __init__(self,lock,timeout = 300):
|
||||
def __init__(self, lock, timeout=300):
|
||||
self._lock = lock
|
||||
self._timeout = timeout
|
||||
|
||||
def __enter__(self):
|
||||
self._lock.acquire_read(self._timeout)
|
||||
|
||||
def __exit__(self,type,value,traceback):
|
||||
self._lock.release_read()
|
||||
|
||||
@@ -48,17 +51,21 @@ class Write_Lock_Instance(object):
|
||||
A context manager for getting exclusive access to the object lock
|
||||
Arguments are lock and timeout (default 5 minutes)
|
||||
"""
|
||||
def __init__(self,lock,timeout = 300):
|
||||
def __init__(self, lock, timeout=300):
|
||||
self._lock = lock
|
||||
self._timeout = timeout
|
||||
|
||||
def __enter__(self):
|
||||
self._lock.acquire_write(self._timeout)
|
||||
|
||||
def __exit__(self,type,value,traceback):
|
||||
self._lock.release_write()
|
||||
|
||||
|
||||
class Lock(object):
|
||||
def __init__(self,file_path):
|
||||
"""Distributed file-based lock using ``flock``."""
|
||||
|
||||
def __init__(self, file_path):
|
||||
self._file_path = file_path
|
||||
self._fd = os.open(file_path,os.O_RDWR)
|
||||
self._reads = 0
|
||||
@@ -71,20 +78,20 @@ def acquire_read(self,timeout):
|
||||
the write lock will be maintained until all locks are released
|
||||
"""
|
||||
if self._reads == 0 and self._writes == 0:
|
||||
self._lock(fcntl.LOCK_SH,timeout)
|
||||
self._lock(fcntl.LOCK_SH, timeout)
|
||||
self._reads += 1
|
||||
|
||||
|
||||
def acquire_write(self,timeout):
|
||||
def acquire_write(self, timeout):
|
||||
"""
|
||||
Implements recursive lock
|
||||
"""
|
||||
if self._writes == 0:
|
||||
self._lock(fcntl.LOCK_EX,timeout)
|
||||
self._lock(fcntl.LOCK_EX, timeout)
|
||||
self._writes += 1
|
||||
|
||||
|
||||
def _lock(self,op,timeout):
|
||||
def _lock(self, op, timeout):
|
||||
"""
|
||||
The timeout is implemented using nonblocking flock()
|
||||
to avoid using signals for timing
|
||||
@@ -96,8 +103,8 @@ def _lock(self,op,timeout):
|
||||
try:
|
||||
fcntl.flock(self._fd, op | fcntl.LOCK_NB)
|
||||
if op == fcntl.LOCK_EX:
|
||||
with open(self._file_path,'w') as f:
|
||||
f.write("pid = "+str(os.getpid())+", host = "+socket.getfqdn())
|
||||
with open(self._file_path, 'w') as f:
|
||||
f.write("pid = " + str(os.getpid()) + ", host = " + socket.getfqdn())
|
||||
return
|
||||
except IOError as error:
|
||||
if error.errno == errno.EAGAIN or error.errno == EACCES:
|
||||
@@ -133,4 +140,4 @@ def _unlock(self):
|
||||
Releases the lock regardless of mode. Note that read locks may be
|
||||
masquerading as write locks at times, but this removes either.
|
||||
"""
|
||||
fcntl.flock(self._fd,fcntl.LOCK_UN)
|
||||
fcntl.flock(self._fd, fcntl.LOCK_UN)
|
||||
|
Reference in New Issue
Block a user