Skip to content

Commit 8aee160

Browse files
committed
feat(base): Create EventCacheStoreLock.
1 parent 2c26a6a commit 8aee160

File tree

1 file changed

+74
-5
lines changed
  • crates/matrix-sdk-base/src/event_cache_store

1 file changed

+74
-5
lines changed

crates/matrix-sdk-base/src/event_cache_store/mod.rs

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@
1919
//! into the event cache for the actual storage. By default this brings an
2020
//! in-memory store.
2121
22-
use std::{str::Utf8Error, sync::Arc};
22+
use std::{fmt, ops::Deref, str::Utf8Error, sync::Arc};
2323

2424
#[cfg(any(test, feature = "testing"))]
2525
#[macro_use]
2626
pub mod integration_tests;
2727
mod memory_store;
2828
mod traits;
2929

30-
use matrix_sdk_common::store_locks::BackingStore;
30+
use matrix_sdk_common::store_locks::{
31+
BackingStore, CrossProcessStoreLock, CrossProcessStoreLockGuard, LockStoreError,
32+
};
3133
pub use matrix_sdk_store_encryption::Error as StoreEncryptionError;
3234

3335
#[cfg(any(test, feature = "testing"))]
@@ -37,6 +39,75 @@ pub use self::{
3739
traits::{DynEventCacheStore, EventCacheStore, IntoEventCacheStore},
3840
};
3941

42+
/// The high-level public type to represent an `EventCacheStore` lock.
43+
pub struct EventCacheStoreLock {
44+
/// The inner cross process lock that is used to lock the `EventCacheStore`.
45+
cross_process_lock: CrossProcessStoreLock<LockableEventCacheStore>,
46+
47+
/// The store itself.
48+
///
49+
/// That's the only place where the store exists.
50+
store: Arc<DynEventCacheStore>,
51+
}
52+
53+
impl fmt::Debug for EventCacheStoreLock {
54+
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
55+
formatter.debug_struct("EventCacheStoreLock").finish_non_exhaustive()
56+
}
57+
}
58+
59+
impl EventCacheStoreLock {
60+
/// Create a new lock around the [`EventCacheStore`].
61+
pub fn new<S>(store: S, key: String, holder: String) -> Self
62+
where
63+
S: IntoEventCacheStore,
64+
{
65+
let store = store.into_event_cache_store();
66+
67+
Self {
68+
cross_process_lock: CrossProcessStoreLock::new(
69+
LockableEventCacheStore(store.clone()),
70+
key,
71+
holder,
72+
),
73+
store,
74+
}
75+
}
76+
77+
/// Acquire a spin lock (see [`CrossProcessLock::spin_lock`]).
78+
pub async fn lock<'a>(&'a self) -> Result<EventCacheStoreLockGuard<'a>, LockStoreError> {
79+
let cross_process_lock_guard = self.cross_process_lock.spin_lock(None).await?;
80+
81+
Ok(EventCacheStoreLockGuard { cross_process_lock_guard, store: self.store.deref() })
82+
}
83+
}
84+
85+
/// An RAII implementation of a “scoped lock” of an [`EventCacheStoreLock`].
86+
/// When this structure is dropped (falls out of scope), the lock will be
87+
/// unlocked.
88+
pub struct EventCacheStoreLockGuard<'a> {
89+
/// The cross process lock guard.
90+
#[allow(unused)]
91+
cross_process_lock_guard: CrossProcessStoreLockGuard,
92+
93+
/// A reference to the store.
94+
store: &'a DynEventCacheStore,
95+
}
96+
97+
impl<'a> fmt::Debug for EventCacheStoreLockGuard<'a> {
98+
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
99+
formatter.debug_struct("EventCacheStoreLockGuard").finish_non_exhaustive()
100+
}
101+
}
102+
103+
impl<'a> Deref for EventCacheStoreLockGuard<'a> {
104+
type Target = DynEventCacheStore;
105+
106+
fn deref(&self) -> &Self::Target {
107+
self.store
108+
}
109+
}
110+
40111
/// Event cache store specific error type.
41112
#[derive(Debug, thiserror::Error)]
42113
pub enum EventCacheStoreError {
@@ -85,10 +156,8 @@ impl EventCacheStoreError {
85156
/// An `EventCacheStore` specific result type.
86157
pub type Result<T, E = EventCacheStoreError> = std::result::Result<T, E>;
87158

88-
/// The public API to read the event cache store: it is behind a cross-process
89-
/// lock.
90159
#[derive(Clone, Debug)]
91-
pub struct LockableEventCacheStore(Arc<dyn EventCacheStore<Error = EventCacheStoreError>>);
160+
struct LockableEventCacheStore(Arc<DynEventCacheStore>);
92161

93162
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
94163
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]

0 commit comments

Comments
 (0)