fixed a major problem with locking in languages, thanks Dan McGee fr the help

This commit is contained in:
Massimo Di Pierro
2012-02-29 13:38:59 -06:00
parent 9c6eafab54
commit 02e7f38da7
7 changed files with 61 additions and 53 deletions
+1 -1
View File
@@ -1 +1 @@
Version 1.99.4 (2012-02-29 11:11:18) stable Version 1.99.4 (2012-02-29 13:38:37) stable
+7 -14
View File
@@ -541,24 +541,17 @@ class BaseAdapter(ConnectionPool):
""" """
to be used ONLY for files that on GAE may not be on filesystem to be used ONLY for files that on GAE may not be on filesystem
""" """
fileobj = open(filename, mode)
if have_portalocker and lock: if have_portalocker and lock:
if mode in ('r','rb'): fileobj = portalocker.LockedFile(filename,mode)
portalocker.lock(fileobj, portalocker.LOCK_SH) else:
elif mode in ('w','wb','a'): fileobj = open(filename,mode)
portalocker.lock(fileobj, portalocker.LOCK_EX)
else:
fileobj.close()
raise RuntimeError, "Unsupported file_open mode"
return fileobj return fileobj
def file_close(self, fileobj, unlock=True): def file_close(self, fileobj):
""" """
to be used ONLY for files that on GAE may not be on filesystem to be used ONLY for files that on GAE may not be on filesystem
""" """
if fileobj: if fileobj:
if have_portalocker and unlock:
portalocker.unlock(fileobj)
fileobj.close() fileobj.close()
def file_delete(self, filename): def file_delete(self, filename):
@@ -3293,7 +3286,7 @@ class UseDatabaseStoredFile:
def file_open(self, filename, mode='rb', lock=True): def file_open(self, filename, mode='rb', lock=True):
return DatabaseStoredFile(self.db,filename,mode) return DatabaseStoredFile(self.db,filename,mode)
def file_close(self, fileobj, unlock=True): def file_close(self, fileobj):
fileobj.close() fileobj.close()
def file_delete(self,filename): def file_delete(self,filename):
@@ -3503,7 +3496,7 @@ class GoogleDatastoreAdapter(NoSQLAdapter):
def file_exists(self, filename): pass def file_exists(self, filename): pass
def file_open(self, filename, mode='rb', lock=True): pass def file_open(self, filename, mode='rb', lock=True): pass
def file_close(self, fileobj, unlock=True): pass def file_close(self, fileobj): pass
def __init__(self,db,uri,pool_size=0,folder=None,db_codec ='UTF-8', def __init__(self,db,uri,pool_size=0,folder=None,db_codec ='UTF-8',
credential_decoder=lambda x:x, driver_args={}, credential_decoder=lambda x:x, driver_args={},
@@ -3854,7 +3847,7 @@ class CouchDBAdapter(NoSQLAdapter):
def file_exists(self, filename): pass def file_exists(self, filename): pass
def file_open(self, filename, mode='rb', lock=True): pass def file_open(self, filename, mode='rb', lock=True): pass
def file_close(self, fileobj, unlock=True): pass def file_close(self, fileobj): pass
def expand(self,expression,field_type=None): def expand(self,expression,field_type=None):
if isinstance(expression,Field): if isinstance(expression,Field):
+1 -2
View File
@@ -437,8 +437,7 @@ class Session(Storage):
response.session_file = \ response.session_file = \
open(response.session_filename, 'rb+') open(response.session_filename, 'rb+')
try: try:
portalocker.lock(response.session_file, portalocker.lock(response.session_file,portalocker.LOCK_EX)
portalocker.LOCK_EX)
response.session_locked = True response.session_locked = True
self.update(cPickle.load(response.session_file)) self.update(cPickle.load(response.session_file))
response.session_file.seek(0) response.session_file.seek(0)
+3 -9
View File
@@ -38,10 +38,8 @@ regex_language = \
def read_dict_aux(filename): def read_dict_aux(filename):
fp = open(filename, 'r') fp = portalocker.LockedFile(filename, 'r')
portalocker.lock(fp, portalocker.LOCK_SH)
lang_text = fp.read().replace('\r\n', '\n') lang_text = fp.read().replace('\r\n', '\n')
portalocker.unlock(fp) # needed or test_languages.py fails
fp.close() fp.close()
if not lang_text.strip(): if not lang_text.strip():
return {} return {}
@@ -91,17 +89,15 @@ def utf8_repr(s):
def write_dict(filename, contents): def write_dict(filename, contents):
try: try:
fp = open(filename, 'w') fp = portalocker.LockedFile(filename, 'w')
except (IOError, OSError): except (IOError, OSError):
if not is_gae: if not is_gae:
logging.warning('Unable to write to file %s' % filename) logging.warning('Unable to write to file %s' % filename)
return return
portalocker.lock(fp, portalocker.LOCK_EX)
fp.write('# coding: utf8\n{\n') fp.write('# coding: utf8\n{\n')
for key in sorted(contents): for key in sorted(contents):
fp.write('%s: %s,\n' % (utf8_repr(key), utf8_repr(contents[key]))) fp.write('%s: %s,\n' % (utf8_repr(key), utf8_repr(contents[key])))
fp.write('}\n') fp.write('}\n')
portalocker.unlock(fp)
fp.close() fp.close()
@@ -312,10 +308,8 @@ def findT(path, language='en-us'):
vp = os.path.join(path, 'views') vp = os.path.join(path, 'views')
for file in listdir(mp, '.+\.py', 0) + listdir(cp, '.+\.py', 0)\ for file in listdir(mp, '.+\.py', 0) + listdir(cp, '.+\.py', 0)\
+ listdir(vp, '.+\.html', 0): + listdir(vp, '.+\.html', 0):
fp = open(file, 'r') fp = portalocker.LockedFile(file, 'r')
portalocker.lock(fp, portalocker.LOCK_EX)
data = fp.read() data = fp.read()
portalocker.unlock(fp)
fp.close() fp.close()
items = regex_translate.findall(data) items = regex_translate.findall(data)
for item in items: for item in items:
+39 -17
View File
@@ -108,22 +108,44 @@ else:
pass pass
if __name__ == '__main__': class LockedFile(object):
from time import time, strftime, localtime def __init__(self,filename, mode='rb'):
import sys self.filename = filename
self.mode = mode
log = open('log.txt', 'a+') self.file = None
lock(log, LOCK_EX) if 'r' in mode:
self.file = open(filename,mode)
timestamp = strftime('%m/%d/%Y %H:%M:%S\n', localtime(time())) lock(self.file,LOCK_SH)
log.write(timestamp) elif 'w' in mode or 'a' in mode:
self.file = open(filename,mode.replace('w','a'))
print 'Wrote lines. Hit enter to release lock.' lock(self.file,LOCK_EX)
dummy = sys.stdin.readline() if not 'a' in mode:
self.file.seek(0)
log.close() self.file.truncate()
else:
raise RuntimeError, "invalid LockedFile(...,mode)"
def read(self,size=None):
return self.file.read() if size is None else self.file.read(size)
def readline(self):
return self.file.readline()
def readlines(self):
return self.file.readlines()
def write(self,data):
self.file.write(data)
self.file.flush()
def close(self):
if not self.file is None:
unlock(self.file)
self.file.close()
self.file = None
def __del__(self):
self.close()
if __name__=='__main__':
f = LockedFile('test.txt',mode='wb')
f.write('test ok')
f.close()
f = LockedFile('test.txt',mode='rb')
print f.read()
f.close()
+6 -9
View File
@@ -172,25 +172,22 @@ class StorageList(Storage):
return self[key] return self[key]
def load_storage(filename): def load_storage(filename):
fp = open(filename, 'rb') fp = None
try: try:
portalocker.lock(fp, portalocker.LOCK_EX) fp = portalocker.LockFile(filename, 'rb')
storage = cPickle.load(fp) storage = cPickle.load(fp)
portalocker.unlock(fp)
finally: finally:
fp.close() if fp: fp.close()
return Storage(storage) return Storage(storage)
def save_storage(storage, filename): def save_storage(storage, filename):
fp = open(filename, 'wb') fp = None
try: try:
portalocker.lock(fp, portalocker.LOCK_EX) fp = portalocker.LockFile(filename, 'wb')
cPickle.dump(dict(storage), fp) cPickle.dump(dict(storage), fp)
portalocker.unlock(fp)
finally: finally:
fp.close() if fp: fp.close()
class Settings(Storage): class Settings(Storage):
+4 -1
View File
@@ -421,7 +421,10 @@ class TestMigrations(unittest.TestCase):
db.commit() db.commit()
def tearDown(self): def tearDown(self):
os.unlink('.storage.db') if os.path.exists('.storage.db'):
os.unlink('.storage.db')
if os.path.exists('.storage.table'):
os.unlink('.storage.table')
class TestReferece(unittest.TestCase): class TestReferece(unittest.TestCase):