Skip to content

Instantly share code, notes, and snippets.

@andr1an
Last active September 11, 2018 11:54
Show Gist options
  • Save andr1an/75a3c50b656c61b084c48608be81c94a to your computer and use it in GitHub Desktop.
Save andr1an/75a3c50b656c61b084c48608be81c94a to your computer and use it in GitHub Desktop.
Python: single instance locking for your scripts
"""Single instance locking for your scripts.
Usage:
from instance_lock import lock_instance
def i_am_busy():
print "I'm busy!"
with lock_instance(locked_callback=i_am_busy):
do_something_long()
"""
import os
import fcntl
import errno
from contextlib import contextmanager
@contextmanager
def lock_instance(filename, locked_callback=None):
"""Gets an instance lock.
Arguments:
filename: a string with lock filename;
locked_callback: a function to be called if lock fails.
"""
assert locked_callback is None or callable(locked_callback)
lock_fp, need_remove = None, False
try:
lock_fp = open(filename, 'w')
fcntl.flock(lock_fp, fcntl.LOCK_NB | fcntl.LOCK_EX)
need_remove = True
yield lock_fp
except IOError as ex_info:
if locked_callback is not None and ex_info.errno == errno.EAGAIN:
locked_callback()
else:
raise
finally:
if lock_fp:
lock_fp.close()
if need_remove:
os.remove(filename)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment