dvc: use zc.lockfile instead of fasteners

fasteners' InterProcessLock doesn't work within
one process, thus it is not suitable for our dvc
library.

Signed-off-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
Ruslan Kuprieiev
2018-02-27 04:20:32 +02:00
parent 713f070ef8
commit 068f742852
4 changed files with 33 additions and 17 deletions
+19 -5
View File
@@ -1,5 +1,7 @@
import os
import fasteners
import time
import zc.lockfile
from dvc.exceptions import DvcException
@@ -13,18 +15,30 @@ class Lock(object):
def __init__(self, dvc_dir):
self.lock_file = os.path.join(dvc_dir, self.LOCK_FILE)
self._lock = fasteners.InterProcessLock(self.lock_file)
self._lock = None
@staticmethod
def init(dvc_dir):
return Lock(dvc_dir)
def lock(self):
if not self._lock.acquire(timeout=self.TIMEOUT):
def _do_lock(self):
try:
self._lock = zc.lockfile.LockFile(self.lock_file)
except zc.lockfile.LockError:
raise LockError('Cannot perform the cmd since DVC is busy and locked. Please retry the cmd later.')
def lock(self):
try:
self._do_lock()
return
except LockError:
time.sleep(self.TIMEOUT)
self._do_lock()
def unlock(self):
self._lock.release()
self._lock.close()
self._lock = None
def __enter__(self):
self.lock()
+1 -1
View File
@@ -1,7 +1,7 @@
boto>=2.46.1
google-compute-engine>=2.4.1 #required by boto
configparser>=3.5.0
fasteners>=0.14.1
zc.lockfile>=1.2.1
future>=0.16.0
google-cloud>=0.24.0
PyInstaller>=3.2.1
+1 -1
View File
@@ -7,7 +7,7 @@ install_requires = [
"boto>=2.46.1",
"google-compute-engine>=2.4.1", #required by boto
"configparser>=3.5.0",
"fasteners>=0.14.1",
"zc.lockfile>=1.2.1",
"future>=0.16.0",
"google-cloud>=0.24.0",
"colorama>=0.3.9",
+12 -10
View File
@@ -1,19 +1,21 @@
from dvc.lock import LockError
from dvc.main import main
from dvc.lock import Lock
from tests.basic_env import TestDvc
class TestLock(TestDvc):
def test_lock(self):
lock = Lock(self.dvc.dvc_dir)
lock.lock()
self.assertTrue(lock._lock.exists())
self.assertTrue(lock._lock.acquired)
lock.unlock()
self.assertFalse(lock._lock.acquired)
def test_with(self):
lock = Lock(self.dvc.dvc_dir)
with lock:
self.assertTrue(lock._lock.acquired)
self.assertFalse(lock._lock.acquired)
with self.assertRaises(LockError):
lock2 = Lock(self.dvc.dvc_dir)
with lock2:
self.assertTrue(False)
def test_cli(self):
lock = Lock(self.dvc.dvc_dir)
with lock:
ret = main(['add', self.FOO])
self.assertEqual(ret, 1)