mycommon-utils 0.1.2

Common utilities library for database operations, Redis caching and system utilities
Documentation
// 宏定义,用于缓存函数结果
// let result = cached_query!(
//         "sys:api:list",
//         60000,
//         async move { service.find_by_id(user.store_id, &person_id).await }
//     );
// #[macro_export]
// macro_rules! cached_query {
//     ($cache_key:expr, $expiry_seconds:expr, $func:expr) => {{
//         use crate::database::redis_util::RedisUtil;
//         use serde::{Serialize, de::DeserializeOwned};
//
//         async fn cached_inner<T, E, F>(
//             cache_key: &str,
//             expiry_seconds: u64,
//             redis_client: &mut RedisUtil,
//             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)) = redis_client.get::<Vec<u8>>(&cache_key) {
//                 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| E::from(e))?;
//                 if let Err(err) = redis_client.set_with_expiry(
//                     cache_key,
//                     &serialized_value, // 直接传递字节数组
//                     expiry_seconds,
//                 ) {
//                     tracing::error!("Failed to set cache for key {}: {}", cache_key, err);
//                 }
//             }
//
//             result
//         }
//
//         let mut redis_client = RedisUtil::new().expect("Failed to create Redis client");
//         cached_inner($cache_key, $expiry_seconds, &mut redis_client, $func).await
//     }};
// }

use crate::database::redis_util::RedisUtil;
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,
{
    async fn cached_inner<T, E, F>(
        cache_key: &str,
        expiry_seconds: u64,
        redis_client: &mut RedisUtil,
        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)) = redis_client.get::<Vec<u8>>(cache_key) {
            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)?;
            if let Err(err) = redis_client.set_with_expiry(
                cache_key,
                &serialized_value, // 直接传递字节数组
                expiry_seconds,
            ) {
                tracing::error!("Failed to set cache for key {}: {}", cache_key, err);
            }
        }

        result
    }

    let mut redis_client = RedisUtil::new().expect("Failed to create Redis client");
    cached_inner(cache_key, expiry_seconds, &mut redis_client, func).await
}