1"""Manages dvc lock file.""" 2 3from __future__ import unicode_literals 4 5import os 6import time 7import zc.lockfile 8 9from dvc.exceptions import DvcException 10 11 12class LockError(DvcException): 13 """Thrown when unable to acquire the lock for dvc repo.""" 14 15 16class Lock(object): 17 """Class for dvc repo lock. 18 19 Args: 20 dvc_dir (str): path to the directory that the lock should be created 21 in. 22 name (str): name of the lock file. 23 """ 24 25 LOCK_FILE = "lock" 26 TIMEOUT = 5 27 28 def __init__(self, dvc_dir, name=LOCK_FILE): 29 self.lock_file = os.path.join(dvc_dir, name) 30 self._lock = None 31 32 def _do_lock(self): 33 try: 34 self._lock = zc.lockfile.LockFile(self.lock_file) 35 except zc.lockfile.LockError: 36 raise LockError( 37 "cannot perform the cmd since DVC is busy and " 38 "locked. Please retry the cmd later." 39 ) 40 41 def lock(self): 42 """Acquire lock for dvc repo.""" 43 try: 44 self._do_lock() 45 return 46 except LockError: 47 time.sleep(self.TIMEOUT) 48 49 self._do_lock() 50 51 def unlock(self): 52 """Release lock for dvc repo.""" 53 self._lock.close() 54 self._lock = None 55 56 def __enter__(self): 57 self.lock() 58 59 def __exit__(self, typ, value, tbck): 60 self.unlock() 61