Skip to main content

mycommon_utils/cached/
mod.rs

1use 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}