distributed-lock-rs
Distributed locks for Rust with multiple backend support. This library provides distributed synchronization primitives (mutex locks, reader-writer locks, semaphores) that work across processes and machines.
Features
- 🔒 Exclusive Locks: Mutual exclusion across processes
- 📖 Reader-Writer Locks: Multiple readers or single writer
- 🎫 Semaphores: Limit concurrent access to N processes
- ⚡ Async/Await: Full async support with tokio
- 🔄 Backend Agnostic: Swap backends without changing application code
- 🔍 Handle Loss Detection: Detect when locks are lost due to connection issues
- 🚀 Production Ready: Connection pooling, automatic lease extension, RedLock support
Backends
PostgreSQL
Uses PostgreSQL advisory locks. Production-ready with connection pooling and transaction-scoped locks.
[]
= "0.1"
= { = "1", = ["full"] }
MySQL
Uses MySQL user-defined variables and database tables. Supports reader-writer locks through automatic table creation.
Note: Reader-writer locks require creating a distributed_locks table in your MySQL database. This table is created automatically when needed, as MySQL doesn't provide built-in reader-writer lock primitives like PostgreSQL.
[]
= "0.1"
= { = "1", = ["full"] }
Or use the meta-crate:
[]
= { = "0.1", = ["mysql"] }
= { = "1", = ["full"] }
Redis
Uses Redis with RedLock algorithm for multi-server deployments. Supports semaphores and automatic lease extension.
[]
= "0.1"
= { = "1", = ["full"] }
File System
Uses OS-level file locking. Simple and requires no external services.
[]
= "0.1"
= { = "1", = ["full"] }
MongoDB
Uses MongoDB's atomic document updates and aggregation pipelines. Production-ready with support for TTL-based expiration.
[]
= "0.1"
= { = "1", = ["full"] }
Meta-Crate (All Backends)
Or use the meta-crate to get all backends:
[]
= "0.1"
= { = "1", = ["full"] }
You can also enable specific backends:
[]
= { = "0.1", = ["mysql", "postgres"] }
= { = "1", = ["full"] }
Quick Start
Basic Usage
use *;
use Duration;
async
PostgreSQL Example
use PostgresLockProvider;
use *;
use Duration;
async
MySQL Example
use MySqlLockProvider;
use *;
use Duration;
async
Redis Example
use RedisLockProvider;
use *;
use Duration;
async
MongoDB Example
use MongoDistributedLock;
use *;
use Duration;
use Client;
async
Reader-Writer Locks
use PostgresLockProvider;
use *;
async
Semaphores
use RedisLockProvider;
use *;
use Duration;
async
Try-Acquire Pattern
Use try_acquire when you want to check if a lock is available without waiting:
match lock.try_acquire.await?
Error Handling
use *;
match lock.acquire.await
Architecture
This library is organized as a Cargo workspace with separate crates:
distributed-lock-core: Core traits and typesdistributed-lock-file: File system backenddistributed-lock-mysql: MySQL backenddistributed-lock-postgres: PostgreSQL backenddistributed-lock-redis: Redis backenddistributed-lock-mongo: MongoDB backenddistributed-lock: Meta-crate re-exporting all backends
Each backend implements the same trait interfaces, allowing you to swap backends without changing application code.
Requirements
- Rust 1.88 or later
- Tokio async runtime (for async operations)
- Backend-specific requirements:
- PostgreSQL: PostgreSQL 9.5+ with
pg_advisory_locksupport - MySQL: MySQL 5.7+ or MariaDB 10.0+ (reader-writer locks create a
distributed_lockstable) - Redis: Redis 2.6+ (Redis 3.0+ recommended)
- MongoDB: MongoDB 4.4+ (uses aggregation pipelines in updates)
- File: Any POSIX-compliant filesystem
- PostgreSQL: PostgreSQL 9.5+ with
License
Licensed under the MIT License (LICENSE or http://opensource.org/licenses/MIT).
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Acknowledgments
This library is inspired by the DistributedLock C# library, ported to Rust with idiomatic patterns and async/await support.