Params: use a multiple-reader / single-writer flock to improve concurrency (#2207)

* improve concurrency: multiple readers, single writer locks

* remove lock in read_db_value
old-commit-hash: 4fba3408c41fad12a75533cf189686601f9e49a6
This commit is contained in:
Dean Lee
2020-09-24 17:51:36 +08:00
committed by GitHub
parent b48d1823e9
commit f5ec24f42f
2 changed files with 13 additions and 38 deletions
+8 -7
View File
@@ -117,14 +117,15 @@ def fsync_dir(path):
class FileLock():
def __init__(self, path, create):
def __init__(self, path, create, lock_ex):
self._path = path
self._create = create
self._fd = None
self._lock_ex = lock_ex
def acquire(self):
self._fd = os.open(self._path, os.O_CREAT if self._create else 0)
fcntl.flock(self._fd, fcntl.LOCK_EX)
fcntl.flock(self._fd, fcntl.LOCK_EX if self._lock_ex else fcntl.LOCK_SH)
def release(self):
if self._fd is not None:
@@ -152,8 +153,8 @@ class DBAccessor():
except KeyError:
return None
def _get_lock(self, create):
lock = FileLock(os.path.join(self._path, ".lock"), create)
def _get_lock(self, create, lock_ex):
lock = FileLock(os.path.join(self._path, ".lock"), create, lock_ex)
lock.acquire()
return lock
@@ -185,7 +186,7 @@ class DBAccessor():
class DBReader(DBAccessor):
def __enter__(self):
try:
lock = self._get_lock(False)
lock = self._get_lock(False, False)
except OSError as e:
# Do not create lock if it does not exist.
if e.errno == errno.ENOENT:
@@ -223,7 +224,7 @@ class DBWriter(DBAccessor):
try:
os.chmod(self._path, 0o777)
self._lock = self._get_lock(True)
self._lock = self._get_lock(True, True)
self._vals = self._read_values_locked()
except Exception:
os.umask(self._prev_umask)
@@ -312,7 +313,7 @@ def write_db(params_path, key, value):
value = value.encode('utf8')
prev_umask = os.umask(0)
lock = FileLock(params_path + "/.lock", True)
lock = FileLock(params_path + "/.lock", True, True)
lock.acquire()
try: