Skip to main content

Production-grade Redlock implementation for Python (Sync + Async)

Project description

Redlock-py

PyPI version CI License: MIT

A production-grade, type-safe, and modern implementation of the Redis Redlock algorithm in Python. Supports both Synchronous and Asynchronous (asyncio) execution.


🏗 Architecture

The Redlock client manages connections to N independent Redis instances. To acquire a lock, it attempts to set a unique token on all instances sequentially. The lock is considered acquired only if:

  1. Quorum (N/2 + 1) instances allow the lock.
  2. Total time taken is less than the lock validity time.
sequenceDiagram
    participant Client
    participant R1 as Redis 1
    participant R2 as Redis 2
    participant R3 as Redis 3 (Quorum)
    participant R4 as Redis 4 
    participant R5 as Redis 5

    Client->>R1: SET resource unique_token NX PX 10000
    R1-->>Client: OK
    Client->>R2: SET resource unique_token NX PX 10000
    R2-->>Client: OK
    Client->>R3: SET resource unique_token NX PX 10000
    R3-->>Client: OK
    
    Note over Client: Quorum reached (3/5)
    
    Client-->>Client: Calculate Drift & Validity
    
    alt Success
        Client->>Client: Return Valid Lock
    else Failure (timeout or no quorum)
        Client->>R1: DEL resource (Unlock)
        Client->>R2: DEL resource (Unlock)
        Client->>R3: DEL resource (Unlock)
    end

🚀 Features

  • Dual Interface: Complete support for Redlock (blocking/sync) and AsyncRedlock (async/await).
  • Type Safe: 100% typed with mypy --strict.
  • Fault Tolerant: Resilient to single node failures.
  • Production Ready: Includes Jitter, Drift calculation, and proper error handling.

📦 Installation

pip install redlock-py
# or with poetry
poetry add redlock-py

💻 Usage

Synchronous

from redlock import Redlock, RedlockConfig

# Configure with list of Redis URIs
config = RedlockConfig(
    masters=[
        "redis://localhost:6379/0",
        "redis://localhost:6380/0",
        "redis://localhost:6381/0",
    ]
)

lock_manager = Redlock(config)

# 1. Standard usage (Non-blocking)
try:
    with lock_manager.lock("my-resource", ttl=10000) as lock:
        if lock.valid:
            print(f"Lock acquired: {lock.resource}")
            # Do critical work...
        else:
            print("Failed to acquire lock")
except Exception:
    pass

# 2. Blocking usage (Wait indefinitely until acquired)
with lock_manager.lock("my-resource", ttl=10000, blocking=True) as lock:
    print("Locked! This might have waited.")

# 3. Explicit Token Unlock (e.g. from a different process)
lock_manager.unlock("my-resource", "previous-token-uuid")

Asynchronous

import asyncio
from redlock import AsyncRedlock, RedlockConfig

async def main():
    config = RedlockConfig(
        masters=[
            "redis://localhost:6379/0",
            "redis://localhost:6380/0",
            "redis://localhost:6381/0",
        ]
    )
    
    lock_manager = AsyncRedlock(config)

    async with lock_manager.lock("my-async-resource", ttl=10000) as lock:
        if lock.valid:
            print("Async lock acquired!")
            await asyncio.sleep(1)

if __name__ == "__main__":
    asyncio.run(main())

🧪 Testing

This project uses a rigorous testing strategy including:

  1. Unit Tests: Mocked Redis interactions.
  2. Integration Tests: Docker-based tests against 5 real Redis nodes.
  3. Fault Injection: Network partition simulations using Toxiproxy.

To run tests:

docker-compose up -d
pytest

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

redlock_ng-2.0.3.tar.gz (6.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

redlock_ng-2.0.3-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

File details

Details for the file redlock_ng-2.0.3.tar.gz.

File metadata

  • Download URL: redlock_ng-2.0.3.tar.gz
  • Upload date:
  • Size: 6.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.14.2 Darwin/25.2.0

File hashes

Hashes for redlock_ng-2.0.3.tar.gz
Algorithm Hash digest
SHA256 17e2c84e3e9729fa979fa0797e64f9b6bf4877236fec479dbde33c5726a5ac6a
MD5 c18f18d857979abaeb34d379c67c0e21
BLAKE2b-256 7412a4083791e0ab38839dd971b25058caa40573a75888d2f4410b872833aa39

See more details on using hashes here.

File details

Details for the file redlock_ng-2.0.3-py3-none-any.whl.

File metadata

  • Download URL: redlock_ng-2.0.3-py3-none-any.whl
  • Upload date:
  • Size: 7.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.14.2 Darwin/25.2.0

File hashes

Hashes for redlock_ng-2.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 a8de33527a3cc297999116d5f050fc7eb72920f6adc38d433be7a4c46445af4c
MD5 0d219c6048bf4f2b4bce98ff59d4c088
BLAKE2b-256 3c7aa13e122f609c32008fa44728f4aa78ac2b90732c558c2f645e7aeb6249b1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page