rsiot/executor/
cache.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use std::{collections::HashMap, sync::Arc};

use futures::Future;
use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};

use crate::message::{Message, MsgDataBound};

type Hash<TMsg> = HashMap<String, Message<TMsg>>;

/// Кеш сообщений
#[derive(Debug)]
pub struct Cache<TMsg>(Arc<RwLock<Hash<TMsg>>>);

impl<TMsg> Cache<TMsg>
where
    TMsg: MsgDataBound,
{
    /// Создаем новый пустой кеш
    pub fn new() -> Self {
        Self(Arc::new(RwLock::new(HashMap::new())))
    }

    /// Блокировка кеша для чтения в синхронном коде
    pub fn blocking_read(&self) -> RwLockReadGuard<'_, Hash<TMsg>> {
        self.0.blocking_read()
    }

    /// Блокировка кеша для чтения
    pub fn read(&self) -> impl Future<Output = RwLockReadGuard<'_, Hash<TMsg>>> {
        self.0.read()
    }

    /// Блокировка кеша для записи
    pub fn write(&self) -> impl Future<Output = RwLockWriteGuard<'_, Hash<TMsg>>> {
        self.0.write()
    }

    /// Очистить кеш
    pub async fn clear(&mut self) {
        let mut lock = self.0.write().await;
        lock.clear()
    }

    /// Вставить сообщение в кеш
    pub async fn insert(&mut self, msg: Message<TMsg>) {
        let mut lock = self.0.write().await;
        let key = msg.key.clone();
        lock.insert(key, msg);
    }
}

impl<TMessage> Clone for Cache<TMessage> {
    fn clone(&self) -> Self {
        Self(self.0.clone())
    }
}

impl<TMessage> Default for Cache<TMessage>
where
    TMessage: MsgDataBound,
{
    fn default() -> Self {
        Self::new()
    }
}