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)
| File | Size | Uploaded | |
|---|---|---|---|
| redishilok-1.1.0.tar.gz | 7.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|