dtypes/redis/rwlock/
reader.rs1use super::lock::RwLock;
2use crate::redis::rwlock::constants::{LOAD_SCRIPT, READER_LOCK_DROP};
3use crate::redis::types::Generic;
4use serde::de::DeserializeOwned;
5use serde::Serialize;
6use std::ops::Deref;
7
8pub struct RwLockReadGuard<'a, T> {
9 lock: &'a RwLock<T>,
10 uuid: usize,
11 conn: redis::Connection,
12 cache: Option<T>,
13}
14
15impl<'a, T> RwLockReadGuard<'a, T>
16where
17 T: Serialize + DeserializeOwned,
18{
19 pub(crate) fn new(lock: &'a RwLock<T>, uuid: usize, conn: redis::Connection) -> Self {
20 Self {
21 lock,
22 uuid,
23 conn,
24 cache: None,
25 }
26 }
27
28 pub fn acquire(&mut self) -> &T {
32 self.cache = self.try_get();
33 self.cache.as_ref().unwrap()
34 }
35
36 fn try_get(&mut self) -> Option<T> {
37 let script = redis::Script::new(LOAD_SCRIPT);
38 let result: Option<String> = script
39 .arg(&self.lock.data.key)
40 .arg(self.uuid)
41 .invoke(&mut self.conn)
42 .expect("Failed to load value. You should not see this!");
43 let result = result?;
44
45 if result == "nil" {
46 return None;
47 }
48 Some(serde_json::from_str(&result).expect("Failed to deserialize value"))
49 }
50}
51
52impl<'a, T> Deref for RwLockReadGuard<'a, T> {
53 type Target = Generic<T>;
54
55 fn deref(&self) -> &Self::Target {
56 &self.lock.data
57 }
58}
59
60impl<T> Drop for RwLockReadGuard<'_, T> {
61 fn drop(&mut self) {
62 let mut conn = self.client.get_connection().unwrap();
63 let _: () = redis::Script::new(READER_LOCK_DROP)
64 .arg(&self.lock.data.key)
65 .arg(self.uuid)
66 .invoke(&mut conn)
67 .unwrap();
68 }
69}