use std::{sync::Arc, time::Duration};
use async_trait::async_trait;
use crate::lock::{LockError, LockResult};
#[derive(Debug, Clone)]
pub struct LockGuard {
key: String,
token: Arc<str>,
ttl: Duration,
}
impl LockGuard {
pub fn new(key: impl Into<String>, token: impl Into<Arc<str>>, ttl: Duration) -> Self {
Self {
key: key.into(),
token: token.into(),
ttl,
}
}
pub fn key(&self) -> &str {
&self.key
}
pub fn ttl(&self) -> Duration {
self.ttl
}
pub(crate) fn token(&self) -> &str {
&self.token
}
}
#[async_trait]
pub trait DistributedLock: Clone + Send + Sync + 'static {
async fn acquire(&self, key: &str, ttl: Duration) -> LockResult<Option<LockGuard>>;
async fn release(&self, guard: &LockGuard) -> LockResult<()>;
async fn try_acquire(&self, key: &str, ttl: Duration) -> LockResult<LockGuard> {
self.acquire(key, ttl).await?.ok_or(LockError::Busy)
}
}