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.4.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.4-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: redlock_ng-2.0.4.tar.gz
  • Upload date:
  • Size: 6.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for redlock_ng-2.0.4.tar.gz
Algorithm Hash digest
SHA256 78f8db4735302009d5e3f06a9b8ce47ea261bebe271bff4c48b0e68bc6e2cb8a
MD5 427687409aae32bf165667df7df8aea6
BLAKE2b-256 862ea622706f2f9a3f0530d413317c562b153b027f3879e2952be3b69b35c3f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for redlock_ng-2.0.4.tar.gz:

Publisher: workflow.yml on alwaysvivek/redlock

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: redlock_ng-2.0.4-py3-none-any.whl
  • Upload date:
  • Size: 7.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for redlock_ng-2.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 3f7919c29acc3e1f04df83198b89e5470978022003151536fc2163b9b195b2cd
MD5 8f650b4e13af985af3c1b39496955961
BLAKE2b-256 4507bd38f2925f069e55b7d8ce573d027fb9a6d3d8bd281ce764d4e65f3d99c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for redlock_ng-2.0.4-py3-none-any.whl:

Publisher: workflow.yml on alwaysvivek/redlock

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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