Skip to main content

Redis Hierarchical Distributed Read-Write Locking

This is a lightweight implementation of a hierarchical distributed read-write lock using Redis.

It supports concurrent readers and exclusive writers in a tree-like hierarchy, ensuring locks on ancestors affect descendants.

Features

  • Hierarchical locking with customizable path separators (e.g., /, :).
  • Concurrent read locks on the same path or ancestors.
  • Exclusive write locks on paths or descendants.
  • Timeout and non-blocking lock options.
  • Automatic lock refreshing for long-running operations.

Installation

pip install redishilok

Usage

import asyncio
from redishilok import RedisHiLok

async def main():
    hilok = RedisHiLok('redis://localhost:6379/0')

    # Acquire a read lock
    async with hilok.read('a/b'):
        print("Read lock acquired on 'a/b'")

        # Acquire a write lock with non-blocking mode
        try:
            async with hilok.write('a', block=False):
                print("Write lock acquired on 'a'")
            print("Never gets here")
        except RuntimeError:
            print("Failed to acquire write lock on 'a'")

asyncio.run(main())

Examples

Basic Hierarchical Locking

import asyncio
from redishilok import RedisHiLok

async def main():
    hilok = RedisHiLok('redis://localhost:6379/0')

    # Concurrent readers
    async with hilok.read('a'):
        async with hilok.read('a/b/c'):
            print("Both read locks succeed")

    # Write lock blocks descendants
    async with hilok.write('a'):
        try:
            async with hilok.read('a/b/c', timeout=0.1):
                pass
        except RuntimeError:
            print("Failed to acquire read lock on 'a/b/c' due to write lock on 'a'")

asyncio.run(main())

Custom Separator

import asyncio
from redishilok import RedisHiLok

async def main():
    hilok = RedisHiLok('redis://localhost', separator=':')
    async with hilok.write('a:b:c'):
        print("Write lock acquired on 'a:b:c'")

asyncio.run(main())

Long-Running Operations with Refresh

import asyncio
from redishilok import RedisHiLok

async def main():
    hilok = RedisHiLok('redis://localhost', ttl=2000, refresh_interval=1000)
    async with hilok.write('a/b'):
        print("Long operation starts")
        await asyncio.sleep(5)  # Lock is automatically refreshed

asyncio.run(main())

Manually-managed Operations with Handles

import asyncio
from redishilok import RedisHiLok

async def main():
    hilok = RedisHiLok('redis://localhost')
    uuid = await hilok.acquire_write('a/b')
    await asyncio.sleep(1)  # Lock is not automatically refreshed, caller must "restore" the lock

    # refresh by uuid, manually
    manual = RedisHiLok('redis://localhost')
    await manual.acquire_write("a/b", uuid=uuid)

    # refresh automatically
    other = RedisHiLok('redis://localhost', refresh_interval=1000)
    async with other.write('a/b', uuid=uuid):
        # lock is auto-refreshing in the background
        pass

    # free resources
    await hilok.close()
    await manual.close()
    await other.close()

asyncio.run(main())

Limitations

  • Requires a running Redis instance.
  • Not suitable for high-frequency locking scenarios (due to Redis round-trips).
  • Lock fairness is not guaranteed (e.g., no queue for blocked writers).

License

MIT

Metadata

Release files for redishilok 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for redishilok 1.1.0
File Size Uploaded
redishilok-1.1.0.tar.gz 7.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for redishilok 1.1.0
File Interpreter ABI Platform
redishilok-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 15.3 kB

Release files / redishilok-1.1.0.tar.gz

Download URL redishilok-1.1.0.tar.gz
Size 7.5 kB
Tags Source
SHA-256 checksum
How to use checksums
60d761e36e7dff915c066776186109d296fb5d04d2abd38cfa0cd08e54885d8b
BLAKE2b-256 checksum
How to use checksums
8a43d0545d4b8d2befe773fb85e803bd190bbbc3d92071890dc0c47dfb8778cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.3 CPython/3.12.3 Windows/10

Release files / redishilok-1.1.0-py3-none-any.whl

Download URL redishilok-1.1.0-py3-none-any.whl
Size 7.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b5c507bbaa18c91f0f8836334052caca397ac48cb5940c0c2cd9ffcf2bb528d7
BLAKE2b-256 checksum
How to use checksums
d1b4e62943ef569f4ded3b7459e313abd738314beec4f73410722cffccedbe02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.3 CPython/3.12.3 Windows/10

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page