use crate::database::redis_util::RedisAsync;
use serde::{Serialize, de::DeserializeOwned};
pub async fn cached_query<T, E, F>(
cache_key: &str,
expiry_seconds: u64,
func: F,
) -> Result<T, E>
where
T: Serialize + DeserializeOwned + Send + Sync + 'static,
E: From<redis::RedisError> + From<serde_json::Error> + Send + 'static,
F: std::future::Future<Output = Result<T, E>> + Send,
{
if let Ok(Some(cached)) = RedisAsync::get::<Vec<u8>>(cache_key).await {
if let Ok(value) = serde_json::from_slice::<T>(&cached) {
tracing::info!("Cache hit for key: {}", cache_key);
return Ok(value);
}
}
let result = func.await;
if let Ok(ref value) = result {
let serialized_value = serde_json::to_vec(value).map_err(E::from)?;
RedisAsync::set_with_expiry(
cache_key,
&serialized_value,
expiry_seconds,
).await.map_err(E::from)?;
}
result
}