Locks
Overview
Redis-backed Mutex and RwLock that mirror tokio::sync, with RAII guards and background lease renewal.
distkit's locks give multiple processes a way to coordinate exclusive (or shared) access to a resource through Redis. The API deliberately mirrors tokio::sync::Mutex and tokio::sync::RwLock, so it should feel familiar.
Enable the lock feature:
[dependencies]
distkit = { version = "0.5", features = ["lock"] }
How they behave
- RAII guards. Acquiring returns a guard. The guard holds no inner data - it is a pure access token. Dropping it releases the lock.
- Background lease renewal. A held lock renews its lease automatically (every
ttl/3) so it survives long critical sections without you touching it. If the holder dies, the lease expires and the lock frees itself. - Awaitable release. Besides dropping, you can call
release()to release explicitly and observe the final guard state. - Writer-preferring
RwLock. A waiting writer blocks new readers, so writers can't be starved by a stream of readers.
A quick look
use distkit::{DistkitRedisKey, lock::{Mutex, RwLock, LockOptions}};
// Mutex - mutual exclusion.
let key = DistkitRedisKey::try_from("invoice_42".to_string())?;
let mutex = Mutex::new(LockOptions::new(key, conn.clone()));
let guard = mutex.lock().await?; // waits until acquired
// ... critical section ...
guard.release().await?;
// RwLock - many readers OR one writer.
let key = DistkitRedisKey::try_from("config_blob".to_string())?;
let rw = RwLock::new(LockOptions::new(key, conn));
let r = rw.read().await?; // shared
r.release().await?;
let w = rw.write().await?; // exclusive
w.release().await?;
Three ways to acquire
Each lock offers the same three acquisition styles:
| Style | Mutex | RwLock (read) | RwLock (write) |
|---|---|---|---|
| Waiting | lock | read | write |
| Non-blocking | try_lock | try_read | try_write |
| Bounded | try_lock_for | try_read_for | try_write_for |

