zen_engine/loader/
cached.rs1use 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}