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