distkit
Locks

Mutex

A distributed mutual-exclusion lock backed by Redis.

Mutex gives at most one holder across all processes sharing the same Redis key. It mirrors tokio::sync::Mutex, minus the inner data - the guard is purely a token that says "you hold the lock".

Construct

use distkit::{DistkitRedisKey, lock::{Mutex, LockOptions}};

let key = DistkitRedisKey::try_from("invoice_42".to_string())?;
let mutex = Mutex::new(LockOptions::new(key, conn));

Mutex::new returns Arc<Mutex>.

Acquiring

// Wait until the lock is free (bounded by max_wait if you set one).
let guard = mutex.lock().await?;

// One non-blocking attempt - errors with LockError::AcquireFail if held.
let guard = mutex.try_lock().await?;

// Wait up to a timeout, polling at retry_interval.
use std::time::Duration;
let guard = mutex
    .try_lock_for(Duration::from_secs(5), Duration::from_millis(50))
    .await?;

Holding and releasing

While you hold the guard, the lease renews in the background, so the critical section can take as long as it needs:

let guard = mutex.lock().await?;
// ... critical section ...
guard.release().await?; // or just drop `guard`

Dropping the guard releases the lock too; release() is the explicit form that lets you await the release and inspect the returned LockGuardState.

Checking the lease

get_state() reports the guard's current state without a Redis round-trip - useful before entering a section that must not run if the lease was lost:

use distkit::lock::LockGuardState;

let guard = mutex.lock().await?;
if guard.get_state().await == LockGuardState::Acquired {
    // safe to proceed
}