Package: redlock
|RedLock logo|RedLock - Distributed locks with Redis and Python-------------------------------------------------|Build Status|This library implements the RedLock algorithm introduced by`@antirez <http://antirez.com/>`__Yet another ...~~~~~~~~~~~~~~~There are already a few redis based lock implementations in the Pythonworld, e.g. `retools <https://github.com/bbangert/retools>`__,`redis-lock <https://pypi.python.org/pypi/redis-lock/0.2.0>`__.However, these libraries can only work with *single-master* redisserver. When the Redis master goes down, your application has to face asingle point of failure . We can't rely on the master-slave replication,because Redis replication is asynchronous.This is an obvious race condition with the master-slave replicationmodel :#. Client A acquires the lock into the master.#. The master crashes before the write to the key is transmitted tothe slave.#. The slave gets promoted to master.#. Client B acquires the lock to the same resource A already holds alock for. SAFETY VIOLATION!A quick introduction to the RedLock algorithm~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~To resolve this problem, the Redlock algorithm assume we have ``N``Redis masters. These nodes are totally independent (no replications). Inorder to acquire the lock, the client will try to acquire the lock inall the N instances sequentially. If and only if the client was able toacquire the lock in the majority (``(N+1)/2``)of the instances, the lockis considered to be acquired.The detailed description of the RedLock algorithm can be found in theRedis documentation: `Distributed locks withRedis <http://redis.io/topics/distlock>`__.APIs~~~~The ``redlock.RedLock`` class shares a similar API with the``threading.Lock`` class in the Python Standard Library.Basic Usage^^^^^^^^^^^.. code:: pythonfrom redlock import RedLock# By default, if no redis connection details are# provided, RedLock uses redis://127.0.0.1:6379/0lock =  RedLock("distributed_lock")lock.acquire()do_something()lock.release()With Statement / Context Manager^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^As with ``threading.Lock``, ``redlock.RedLock`` objects are contextmanagers thus support the `WithStatement <https://docs.python.org/2/reference/datamodel.html#context-managers>`__.This way is more pythonic and recommended... code:: pythonfrom redlock import RedLockwith RedLock("distributed_lock"):do_something()Specify multiple Redis nodes^^^^^^^^^^^^^^^^^^^^^^^^^^^^.. code:: pythonfrom redlock import RedLockwith RedLock("distributed_lock",connection_details=[{'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},{'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},{'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},{'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},]):do_something()| The ``connection_details`` parameter expects a list of keywordarguments for initializing Redis clients.| Other acceptable Redis client arguments can be found on the `redis-pydoc <http://redis-py.readthedocs.org/en/latest/#redis.StrictRedis>`__.Reuse Redis clients with the RedLockFactory^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Usually the connection details of the Redis nodes are fixed.``RedLockFactory`` can help reuse them, create multiple RedLocks butonly initialize the clients once... code:: pythonfrom redlock import RedLockFactoryfactory = RedLockFactory(connection_details=[{'host': 'xxx.xxx.xxx.xxx'},{'host': 'xxx.xxx.xxx.xxx'},{'host': 'xxx.xxx.xxx.xxx'},{'host': 'xxx.xxx.xxx.xxx'},])with factory.create_lock("distributed_lock"):do_something()with factory.create_lock("another_lock"):do_something().. |RedLock logo| image:: https://github.com/glasslion/redlock/raw/master/docs/assets/redlock-small.png.. |Build Status| image:: https://travis-ci.org/glasslion/redlock.svg?branch=master:target: https://travis-ci.org/glasslion/redlock