# async-redis-lock
[](https://crates.io/crates/redis-lock)
[](https://docs.rs/redis-lock)
A simple and easy-to-use asynchronous redis distributed lock implementation based on tokio and redis-rs.
## Key Features
- ✨ **Auto Extension** - Automatically extends lock lifetime in background until released
- 🔒 **Passive Release** - Lock automatically releases when lifetime expires after process crash
- 🎯 **Drop Support** - Supports both implicit release via drop and explicit release via method call
## Quick Start
### Installation
```toml
[dependencies]
async-redis-lock = "0.0.1"
```
### Basic Usage
```rust
use async_redis_lock::Locker;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create locker
let mut locker = Locker::from_redis_url("redis://127.0.0.1:6379/0").await?;
// Acquire lock
let lock = locker.acquire("lock_key").await?;
// At this point:
// 1. Lock is held
// 2. Background task automatically extends lock TTL
// 3. Safe to perform critical operations
// ...
// Release lock explicitly
// Alternative: drop(lock) for implicit release
lock.release()?;
Ok(())
}
```
### Automatic Release
```rust
use async_redis_lock::Locker;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut locker = Locker::from_redis_url("redis://127.0.0.1:6379/0").await?;
// Use block scope to control lock lifetime
{
// Acquire lock and store in _lock variable
// The _ prefix indicates we only care about its Drop behavior
let _lock = locker.acquire("lock_key").await?;
// Perform operations that require locking
// ...
// Lock will be automatically released when block ends
// Thanks to Rust's Drop trait implementation
}
Ok(())
}
```
### Advanced Configuration
```rust
use async_redis_lock::Locker;
use async_redis_lock::options::Options;
use std::time::Duration;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut locker = Locker::from_redis_url("redis://127.0.0.1:6379/0").await?;
// Build a custom lock options
let opts = Options::new()
// Set interval between acquisition attempts
// Default: 100ms
.retry(Duration::from_millis(100))
// Set maximum time to attempt acquisition
// Default: Some(1s)
// Note: none means retry indefinitely
.timeout(Some(Duration::from_secs(1)))
// Set lock time-to-live before auto-release
// Default: 3s
.ttl(Duration::from_secs(3))
// Set lock auto-extend interval
// Default: 1s
// Recommend: lifetime/3
.extend(Duration::from_secs(1));
// Acquire lock with the custom options
let _lock = locker.acquire_with_options(&opts, "lock_key").await?;
// Perform operations that require locking
// ...
Ok(())
}
```
## Important Notes
1. Don't ignore the return value of acquire method, or the lock will release immediately
2. extend_interval must be less than lifetime to prevent unintended release
3. Lock implements Drop trait and will auto-release when out of scope
## License
MIT
Contributions and suggestions are welcome!