Skip to main content

DistributedLockBackend

Trait DistributedLockBackend 

Source
pub trait DistributedLockBackend:
    Send
    + Sync
    + Debug {
    // Required methods
    fn try_acquire<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        key: &'life1 str,
        owner: &'life2 str,
        ttl_secs: u64,
    ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn release<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        key: &'life1 str,
        owner: &'life2 str,
    ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn renew<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        key: &'life1 str,
        owner: &'life2 str,
        ttl_secs: u64,
    ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn is_locked<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn owner<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Option<String>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn release_all<'life0, 'life1, 'async_trait>(
        &'life0 self,
        owner: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<u64>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
}
Expand description

Backend for distributed lock management.

Used by the beat scheduler to prevent duplicate task execution across multiple scheduler instances. Each implementation provides atomic lock operations with TTL-based expiration.

§Lock Semantics

  • Locks are identified by a string key (typically the task name)
  • Each lock has an owner (typically the scheduler instance ID)
  • Locks expire after a configurable TTL to prevent deadlocks
  • Only the owner can release or renew a lock

§Example

use celers_core::lock::DistributedLockBackend;

async fn schedule_task(backend: &dyn DistributedLockBackend) {
    let acquired = backend.try_acquire("my_task", "scheduler-1", 300).await.unwrap();
    if acquired {
        // Execute the task
        // ...
        backend.release("my_task", "scheduler-1").await.unwrap();
    }
}

Required Methods§

Source

fn try_acquire<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 str, owner: &'life2 str, ttl_secs: u64, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Try to acquire a lock. Returns Ok(true) if acquired successfully.

If the lock is already held by the same owner, this should return Ok(true). If the lock is held by a different owner and has not expired, returns Ok(false). If the lock has expired, it may be acquired by the new owner.

§Arguments
  • key - Lock identifier (typically the task name)
  • owner - Owner identifier (typically the scheduler instance ID)
  • ttl_secs - Time-to-live for the lock in seconds
Source

fn release<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 str, owner: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Release a lock. Returns Ok(true) if released (was owned by this owner).

Only the current owner can release a lock. Returns Ok(false) if the lock does not exist or is owned by a different owner.

§Arguments
  • key - Lock identifier
  • owner - Owner identifier (must match the lock’s owner)
Source

fn renew<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 str, owner: &'life2 str, ttl_secs: u64, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Renew/extend a lock’s TTL. Returns Ok(true) if renewed.

Only the current owner can renew a lock. The lock must not have expired. Returns Ok(false) if the lock does not exist, is owned by a different owner, or has already expired.

§Arguments
  • key - Lock identifier
  • owner - Owner identifier (must match the lock’s owner)
  • ttl_secs - New time-to-live for the lock in seconds
Source

fn is_locked<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Check if a lock is currently held by anyone.

Returns Ok(true) if the lock exists and has not expired.

Source

fn owner<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get the current owner of a lock, if any.

Returns Ok(None) if the lock does not exist or has expired.

Source

fn release_all<'life0, 'life1, 'async_trait>( &'life0 self, owner: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<u64>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Release all locks owned by a specific owner.

Returns the number of locks that were released. This is useful for cleanup when a scheduler instance shuts down.

Implementors§