bark/lock_manager/
memory.rs1use std::sync::OnceLock;
33use std::time::Duration;
34
35use super::{LockGuard, LockManager};
36use super::internal_memory::InternalMemoryLockManager;
37
38pub struct MemoryLockManager;
42
43impl MemoryLockManager {
44 pub fn new() -> Self {
45 let _ = Self::shared();
48 Self
49 }
50
51 fn shared() -> &'static InternalMemoryLockManager {
52 static SHARED: OnceLock<InternalMemoryLockManager> = OnceLock::new();
53 SHARED.get_or_init(InternalMemoryLockManager::new)
54 }
55}
56
57impl Default for MemoryLockManager {
58 fn default() -> Self { Self::new() }
59}
60
61impl std::fmt::Debug for MemoryLockManager {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 f.debug_struct("MemoryLockManager").finish()
64 }
65}
66
67#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
68#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
69impl LockManager for MemoryLockManager {
70 async fn try_lock(&self, key: &str) -> Option<Box<dyn LockGuard>> {
71 Self::shared().try_lock(key).await
72 }
73
74 async fn lock(&self, key: &str, timeout: Duration) -> anyhow::Result<Box<dyn LockGuard>> {
75 Self::shared().lock(key, timeout).await
76 }
77}
78
79#[cfg(all(test, not(target_arch = "wasm32")))]
81mod test {
82 use super::*;
83
84 #[tokio::test]
85 async fn two_instances_share_keys() {
86 let a = MemoryLockManager::new();
87 let b = MemoryLockManager::new();
88 let g = a.try_lock("bark.shared.test").await.unwrap();
89 let busy = b.try_lock("bark.shared.test").await;
90 assert!(busy.is_none(), "second instance should observe the lock");
91 drop(g);
92 let g2 = b.try_lock("bark.shared.test").await;
93 assert!(g2.is_some(), "second instance can acquire after release");
94 }
95}