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