Add remove external lock files API in lockutils

when external lock are used, there will be a lock files which
is used for external file lock, it will not be removed and remain
forever. it will be a problem when tens of thousands of this kind
of actions. Add a API to allow other component to remove lock file
internal lock will be acquired before further action

Change-Id: I4d996b91bcc55becb0ebf4ec77ac80546f433ae9
Closes-Bug: 1256306
This commit is contained in:
jichenjc
2014-01-25 06:35:31 +08:00
parent c7e9452b32
commit 48e09f934b
2 changed files with 43 additions and 11 deletions

View File

@@ -143,26 +143,43 @@ _semaphores = weakref.WeakValueDictionary()
_semaphores_lock = threading.Lock()
def _get_lock_path(name, lock_file_prefix):
# NOTE(mikal): the lock name cannot contain directory
# separators
name = name.replace(os.sep, '_')
if lock_file_prefix:
sep = '' if lock_file_prefix.endswith('-') else '-'
name = '%s%s%s' % (lock_file_prefix, sep, name)
if not CONF.lock_path:
raise cfg.RequiredOptError('lock_path')
return os.path.join(CONF.lock_path, name)
def external_lock(name, lock_file_prefix=None):
with internal_lock(name):
LOG.debug(_('Attempting to grab external lock "%(lock)s"'),
{'lock': name})
# NOTE(mikal): the lock name cannot contain directory
# separators
name = name.replace(os.sep, '_')
if lock_file_prefix:
sep = '' if lock_file_prefix.endswith('-') else '-'
name = '%s%s%s' % (lock_file_prefix, sep, name)
if not CONF.lock_path:
raise cfg.RequiredOptError('lock_path')
lock_file_path = os.path.join(CONF.lock_path, name)
lock_file_path = _get_lock_path(name, lock_file_prefix)
return InterProcessLock(lock_file_path)
def remove_external_lock_file(name, lock_file_prefix=None):
"""Remove a external lock file when it's not used anymore
This will be helpful when we have a lot of lock files
"""
with internal_lock(name):
lock_file_path = _get_lock_path(name, lock_file_prefix)
try:
os.remove(lock_file_path)
except OSError:
LOG.info(_('Failed to remove file %(file)s'),
{'file': lock_file_path})
def internal_lock(name):
with _semaphores_lock:
try:

View File

@@ -314,6 +314,21 @@ class LockTestCase(test.BaseTestCase):
self.assertRaises(cfg.RequiredOptError, foo)
def test_remove_lock_external_file(self):
lock_name = 'mylock'
lock_pfix = 'mypfix-remove-lock-test-'
lock_dir = tempfile.mkdtemp()
self.config(lock_path=lock_dir)
lockutils.remove_external_lock_file(lock_name, lock_pfix)
for ent in os.listdir(lock_dir):
self.assertRaises(OSError, ent.startswith, lock_pfix)
if os.path.exists(lock_dir):
shutil.rmtree(lock_dir, ignore_errors=True)
class LockutilsModuleTestCase(test.BaseTestCase):