zen_engine/loader/
cached.rs

1use ahash::{HashMap, HashMapExt};
2use std::future::Future;
3use std::pin::Pin;
4use std::sync::Arc;
5use tokio::sync::Mutex;
6
7use crate::loader::{DecisionLoader, DynamicLoader, LoaderResponse};
8use crate::model::DecisionContent;
9
10#[derive(Debug)]
11pub struct CachedLoader {
12    loader: DynamicLoader,
13    cache: Mutex<HashMap<String, Arc<DecisionContent>>>,
14}
15
16impl From<DynamicLoader> for CachedLoader {
17    fn from(value: DynamicLoader) -> Self {
18        Self {
19            loader: value,
20            cache: Mutex::new(HashMap::new()),
21        }
22    }
23}
24
25impl DecisionLoader for CachedLoader {
26    fn load<'a>(
27        &'a self,
28        key: &'a str,
29    ) -> Pin<Box<dyn Future<Output = LoaderResponse> + 'a + Send>> {
30        Box::pin(async move {
31            let mut cache = self.cache.lock().await;
32            if let Some(content) = cache.get(key) {
33                return Ok(content.clone());
34            }
35
36            let decision_content = self.loader.load(key).await?;
37            cache.insert(key.to_string(), decision_content.clone());
38            Ok(decision_content)
39        })
40    }
41}