Skip to content

Commit f705251

Browse files
committed
refactor: Implement try_take_leased_lock on MemoryStore.
1 parent 93c6eb3 commit f705251

File tree

1 file changed

+49
-3
lines changed

1 file changed

+49
-3
lines changed

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

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use std::{num::NonZeroUsize, sync::RwLock as StdRwLock};
15+
use std::{
16+
collections::{hash_map::Entry, HashMap},
17+
num::NonZeroUsize,
18+
sync::RwLock as StdRwLock,
19+
time::{Duration, Instant},
20+
};
1621

1722
use async_trait::async_trait;
1823
use matrix_sdk_common::ring_buffer::RingBuffer;
@@ -28,14 +33,18 @@ use crate::media::{MediaRequest, UniqueKey as _};
2833
#[derive(Debug)]
2934
pub struct MemoryStore {
3035
media: StdRwLock<RingBuffer<(OwnedMxcUri, String /* unique key */, Vec<u8>)>>,
36+
leases: StdRwLock<HashMap<String, (String, Instant)>>,
3137
}
3238

3339
// SAFETY: `new_unchecked` is safe because 20 is not zero.
3440
const NUMBER_OF_MEDIAS: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(20) };
3541

3642
impl Default for MemoryStore {
3743
fn default() -> Self {
38-
Self { media: StdRwLock::new(RingBuffer::new(NUMBER_OF_MEDIAS)) }
44+
Self {
45+
media: StdRwLock::new(RingBuffer::new(NUMBER_OF_MEDIAS)),
46+
leases: Default::default(),
47+
}
3948
}
4049
}
4150

@@ -57,7 +66,44 @@ impl EventCacheStore for MemoryStore {
5766
key: &str,
5867
holder: &str,
5968
) -> Result<bool, Self::Error> {
60-
todo!()
69+
let now = Instant::now();
70+
let expiration = now + Duration::from_millis(lease_duration_ms.into());
71+
72+
match self.leases.write().unwrap().entry(key.to_owned()) {
73+
// There is an existing holder.
74+
Entry::Occupied(mut entry) => {
75+
let (current_holder, current_expiration) = entry.get_mut();
76+
77+
if current_holder == holder {
78+
// We had the lease before, extend it.
79+
*current_expiration = expiration;
80+
81+
Ok(true)
82+
} else {
83+
// We didn't have it.
84+
if *current_expiration < now {
85+
// Steal it!
86+
*current_holder = holder.to_owned();
87+
*current_expiration = expiration;
88+
89+
Ok(true)
90+
} else {
91+
// We tried our best.
92+
Ok(false)
93+
}
94+
}
95+
}
96+
97+
// There is no holder, easy.
98+
Entry::Vacant(entry) => {
99+
entry.insert((
100+
holder.to_owned(),
101+
Instant::now() + Duration::from_millis(lease_duration_ms.into()),
102+
));
103+
104+
Ok(true)
105+
}
106+
}
61107
}
62108

63109
async fn add_media_content(&self, request: &MediaRequest, data: Vec<u8>) -> Result<()> {

0 commit comments

Comments
 (0)