mycommon_utils/cached/
mod.rs1use crate::database::redis_util::RedisAsync;
2use serde::{Serialize, de::DeserializeOwned};
3pub async fn cached_query<T, E, F>(
4 cache_key: &str,
5 expiry_seconds: u64,
6 func: F,
7) -> Result<T, E>
8where
9 T: Serialize + DeserializeOwned + Send + Sync + 'static,
10 E: From<redis::RedisError> + From<serde_json::Error> + Send + 'static,
11 F: std::future::Future<Output = Result<T, E>> + Send,
12{
13 if let Ok(Some(cached)) = RedisAsync::get::<Vec<u8>>(cache_key).await {
14 if let Ok(value) = serde_json::from_slice::<T>(&cached) {
15 tracing::info!("Cache hit for key: {}", cache_key);
16 return Ok(value);
17 }
18 }
19
20 let result = func.await;
21 if let Ok(ref value) = result {
22 let serialized_value = serde_json::to_vec(value).map_err(E::from)?;
23 RedisAsync::set_with_expiry(
24 cache_key,
25 &serialized_value,
26 expiry_seconds,
27 ).await.map_err(E::from)?;
28 }
29
30 result
31}