distkit
Locks

Guard state & errors

Reading a guard's lease state and handling acquisition failures.

A lock guard tracks the state of its lease. Because the lease renews in the background, it's possible (rarely) for a guard to lose its lease mid-section - for instance, if Redis was briefly unreachable past the ttl. LockGuardState lets you observe that.

LockGuardState

pub enum LockGuardState {
    Acquired, // held, lease is being renewed
    Lost,     // a refresh failed; the lease is presumed gone (may still recover)
    Released, // released, no longer held
}

Every guard - MutexGuard, RwLockReadGuard, RwLockWriteGuard - exposes:

// Inspect the current state. No Redis round-trip.
async fn get_state(&self) -> LockGuardState;

// Release explicitly and return the resulting state.
async fn release(self) -> Result<LockGuardState, DistkitError>;

Checking before a critical section

Lost is the state to guard against: it means the lock may no longer be exclusively yours.

use distkit::lock::LockGuardState;

let guard = mutex.lock().await?;

match guard.get_state().await {
    LockGuardState::Acquired => {
        // safe - do the protected work
    }
    LockGuardState::Lost => {
        // lease slipped; bail out instead of risking a double-run
        return Ok(());
    }
    LockGuardState::Released => unreachable!("we still hold the guard"),
}

Acquisition errors

Acquiring can fail with a LockError (surfaced as DistkitError::LockError). The two you handle routinely mean "the lock is busy", not "something broke":

  • AcquireFail - a non-blocking try_* call would have had to wait.
  • Timeout { waited } - a bounded *_for call ran out of time.
use distkit::{DistkitError, lock::LockError};

match mutex.try_lock().await {
    Ok(guard) => { /* got it */ }
    Err(DistkitError::LockError(LockError::AcquireFail)) => {
        // someone else holds it - back off and retry later
    }
    Err(e) => return Err(e.into()),
}

The remaining variants (NotOwner, InvalidTtl, InvalidOwner) indicate misuse or bad configuration rather than contention.