Package: sherlock
Sherlock is a library that provides easy-to-use distributed inter-process
locks and also allows you to choose a backend of your choice for lock
synchronization.OverviewWhen you are working with resources which are accessed by multiple services or
distributed services, more than often you need some kind of locking mechanism
to make it possible to access some resources at a time.Distributed Locks or Mutexes can help you with this. Sherlock provides
the exact same facility, with some extra goodies. It provides an easy-to-use API
that resembles standard library’sthreading.Locksemantics.Apart from this, Sherlock gives you the flexibility of using a backend of
your choice for managing locks.Sherlock also makes it simple for you to extend Sherlock to use
backends that are not supported.FeaturesAPI similar to standard library’sthreading.Lock.Support for With statement, to cleanly acquire and release locks.Backend agnostic: supports File,Redis,Memcached,Etcd, andKubernetesas choice of
backends.Extendable: can be easily extended to work with any other of backend of
choice by extending base lock class. Readextending.Supported Backends and Client LibrariesFollowing client libraries are supported for every supported backend:File:filelockRedis:redis-pyMemcached:pylibmcEtcd:python-etcdKubernetes:kubernetesAs of now, only the above mentioned libraries are supported. Although
Sherlock takes custom client objects so that you can easily provide
settings that you want to use for that backend store, but Sherlock also
checks if the provided client object is an instance of the supported clients
and accepts client objects which pass this check, even if the APIs are the
same. Sherlock might get rid of this issue later, if need be and if
there is a demand for that.InstallationInstallation is simple.pipinstallsherlock[all]NoteSherlock will install all the client libraries for all the
supported backends.Basic UsageSherlock is simple to use as at the API and semantics level, it tries to
conform to standard library’sthreading.LockAPIs.importsherlockfromsherlockimportLock# Configure Sherlock's locks to use Redis as the backend,# never expire locks and retry acquiring an acquired lock after an# interval of 0.1 second.sherlock.configure(backend=sherlock.backends.REDIS,expire=None,retry_interval=0.1)# Note: configuring sherlock to use a backend does not limit you# another backend at the same time. You can import backend specific locks# like RedisLock, MCLock and EtcdLock and use them just the same way you# use a generic lock (see below). In fact, the generic Lock provided by# sherlock is just a proxy that uses these specific locks under the hood.# acquire a lock called my_locklock=Lock('my_lock')# acquire a blocking locklock.acquire()# check if the lock has been acquired or notlock.locked()==True# attempt to renew the locklock.renew()# release the locklock.release()Support forwithstatement# using with statementwithLock('my_lock')aslock:# do something constructive with your locked resource herepassBlocking and Non-blocking API# acquire non-blocking locklock1=Lock('my_lock')lock2=Lock('my_lock')# successfully acquire lock1lock1.acquire()# try to acquire lock in a non-blocking waylock2.acquire(False)==True# returns False# try to acquire lock in a blocking waylock2.acquire()# blocks until lock is acquired to timeout happensUsing two backends at the same timeConfiguring Sherlock to use a backend does not limit you from using
another backend at the same time. You can import backend specific locks like
RedisLock, MCLock and EtcdLock and use them just the same way you use a generic
lock (see below). In fact, the generic Lock provided by Sherlock is just
a proxy that uses these specific locks under the hood.importsherlockfromsherlockimportLock# Configure Sherlock's locks to use Redis as the backendsherlock.configure(backend=sherlock.backends.REDIS)# Acquire a lock called my_lock, this lock uses Redislock=Lock('my_lock')# Now acquire locks in MemcachedfromsherlockimportMCLockmclock=MCLock('my_mc_lock')mclock.acquire()TestsTo run all the tests (including integration), you have to make sure that all
the databases are running. Make sure all the services are running:# memcachedmemcached# redis-serverredis-server# etcd (etcd is probably not available as package, here is the simplest way
# to run it).wgethttps://github.com/coreos/etcd/releases/download/<version>/etcd-<version>-<platform>.tar.gztar-zxvfetcd-<version>-<platform>.gz./etcd-<version>-<platform>/etcdRun tests like so:pythonsetup.pytestDocumentationAvailablehere.LicenseSeeLICENSE.In short: This is an open-source project and exists for anyone to use it
and/or modify it for personal use. Just be nice and attribute the credits
wherever you can. :)Questions?You are encouraged to ask questions usingissuesas that helps everyone and
myself when people with better know-how contribute to the discussion. However,
if you wish to get in touch with me personally, then I can be contacted atkapoor.vaidik++github+sherlock@gmail.com.Distributed Locking in Other LanguagesNodeJS -https://github.com/thedeveloper/warlock