提交 a6daeabb authored 作者: Arnaud Bergeron's avatar Arnaud Bergeron

Add the host to the lock file and use it to determine if the other process

is local and already dead (in which case we steal the lock immediatly). Otherwise the old comportement is kept (steal the lock after 120 seconds of inactivity). The code is made to deal with old locks it could encountered by treating those locks as coming from other hosts so there should not be any functional changes.
上级 1ae40316
...@@ -130,7 +130,7 @@ def lock(tmp_dir, timeout=120, min_wait=5, max_wait=10, verbosity=1): ...@@ -130,7 +130,7 @@ def lock(tmp_dir, timeout=120, min_wait=5, max_wait=10, verbosity=1):
if not os.path.isdir(base_lock): if not os.path.isdir(base_lock):
try: try:
os.makedirs(base_lock) os.makedirs(base_lock)
except: except OSError:
# Someone else was probably trying to create it at the same time. # Someone else was probably trying to create it at the same time.
# We wait two seconds just to make sure the following assert does # We wait two seconds just to make sure the following assert does
# not fail on some NFS systems. # not fail on some NFS systems.
...@@ -148,19 +148,34 @@ def lock(tmp_dir, timeout=120, min_wait=5, max_wait=10, verbosity=1): ...@@ -148,19 +148,34 @@ def lock(tmp_dir, timeout=120, min_wait=5, max_wait=10, verbosity=1):
try: try:
last_owner = 'no_owner' last_owner = 'no_owner'
time_start = time.time() time_start = time.time()
other_dead = False
while os.path.isdir(tmp_dir): while os.path.isdir(tmp_dir):
try: try:
read_owner = open(lock_file).readlines()[0].strip() read_owner = open(lock_file).readlines()[0].strip()
# The following line does nothing but raise an exception # the try is transtion code for old locks
# if somehow something is wrong in the owner format, to # it may be removed when poeple have upgraded
# avoid crashing later on. try:
read_owner.split('_')[0] other_host = read_owner.split('_')[2]
except: except IndexError:
other_host = () # make sure it isn't equal to any host
if other_host == os.uname()[1]:
try:
os.kill(int(read_owner.split('_')[0]), 0)
except OSError:
other_dead = True
except Exception:
read_owner = 'failure' read_owner = 'failure'
if other_dead:
if not no_display:
msg = "process '%s'" % read_owner.split('_')[0]
warning("Overriding existing lock by dead %s (I am "
"process '%s')"% (msg, my_pid))
get_lock.unlocker.unlock()
continue
if last_owner == read_owner: if last_owner == read_owner:
if (timeout is not None and if (timeout is not None and
time.time() - time_start >= timeout): time.time() - time_start >= timeout):
# Timeout exceeded. # Timeout exceeded or locking process dead.
if not no_display: if not no_display:
if read_owner == 'failure': if read_owner == 'failure':
msg = 'unknown process' msg = 'unknown process'
...@@ -188,7 +203,7 @@ def lock(tmp_dir, timeout=120, min_wait=5, max_wait=10, verbosity=1): ...@@ -188,7 +203,7 @@ def lock(tmp_dir, timeout=120, min_wait=5, max_wait=10, verbosity=1):
try: try:
os.mkdir(tmp_dir) os.mkdir(tmp_dir)
except: except OSError:
# Error while creating the directory: someone else must have tried # Error while creating the directory: someone else must have tried
# at the exact same time. # at the exact same time.
continue continue
...@@ -217,11 +232,13 @@ def refresh_lock(lock_file): ...@@ -217,11 +232,13 @@ def refresh_lock(lock_file):
'Refresh' an existing lock by re-writing the file containing the owner's 'Refresh' an existing lock by re-writing the file containing the owner's
unique id, using a new (randomly generated) id, which is also returned. unique id, using a new (randomly generated) id, which is also returned.
""" """
unique_id = '%s_%s' % (os.getpid(), unique_id = '%s_%s_%s' % (os.getpid(),
''.join([str(random.randint(0,9)) for i in range(10)])) ''.join([str(random.randint(0,9)) for i in range(10)]),
os.uname()[1])
lock_write = open(lock_file, 'w') lock_write = open(lock_file, 'w')
lock_write.write(unique_id + '\n') lock_write.write(unique_id + '\n')
lock_write.close() lock_write.close()
print lock_file
return unique_id return unique_id
class Unlocker(object): class Unlocker(object):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论