daoyi_cloud_common/redis/
mod.rs

1use crate::config::RedisConfig;
2use deadpool_redis::redis::cmd;
3use deadpool_redis::{Config, Pool, Runtime};
4use std::sync::OnceLock;
5
6static REDIS_ENGINE: OnceLock<Pool> = OnceLock::new();
7// 初始化连接池
8pub async fn init_redis_pool(config: &RedisConfig) {
9    let connection_string = match &config.password {
10        Some(password) => format!(
11            "redis://{}@{}:{}/{}",
12            password, config.host, config.port, config.db
13        ),
14        None => format!("redis://{}:{}/{}", config.host, config.port, config.db),
15    };
16    let cfg = Config::from_url(connection_string);
17    let pool = cfg
18        .create_pool(Some(Runtime::Tokio1))
19        .expect("Failed to create Redis Pool");
20    REDIS_ENGINE.set(pool).expect("redis pool should be set");
21}
22
23fn redis_engine() -> &'static Pool {
24    REDIS_ENGINE.get().expect("redis should be initialized")
25}
26
27async fn get_redis_client() -> deadpool_redis::Connection {
28    redis_engine()
29        .get()
30        .await
31        .expect("Failed to get Redis client")
32}
33
34pub struct RedisClient {
35    client: deadpool_redis::Connection,
36}
37
38impl RedisClient {
39    pub async fn build() -> Self {
40        let client = get_redis_client().await;
41        Self { client }
42    }
43
44    pub async fn set(&mut self, key: &str, value: &str) {
45        cmd("SET")
46            .arg(&[key, value])
47            .query_async::<()>(&mut self.client)
48            .await
49            .expect("Failed to set redis value");
50    }
51
52    pub async fn get(&mut self, key: &str) -> String {
53        let value: String = cmd("GET")
54            .arg(&[key])
55            .query_async(&mut self.client)
56            .await
57            .unwrap();
58        value
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use crate::config::ServerConfig;
65    use crate::redis::RedisClient;
66    use crate::{config, redis};
67    use config::{Env, Format, Toml};
68    use figment::Figment;
69
70    #[tokio::test]
71    async fn test_redis_client() {
72        let profile = Env::var("APP_PROFILE").unwrap_or_else(|| "test".to_string());
73        let data = Toml::file(
74            Env::var("APP_CONFIG")
75                .as_deref()
76                .unwrap_or(format!("config-{}.toml", profile).as_str()),
77        );
78        let raw_config = Figment::new().merge(data);
79        let config = match raw_config.extract::<ServerConfig>() {
80            Ok(s) => s,
81            Err(e) => {
82                eprintln!(
83                    "It looks like your config is invalid. The following error occurred: {e}"
84                );
85                std::process::exit(1);
86            }
87        };
88
89        redis::init_redis_pool(&config.redis).await;
90
91        let mut redis_client = RedisClient::build().await;
92        redis_client.set("deadpool/test_key", "42").await;
93        let value: String = redis_client.get("deadpool/test_key").await;
94        assert_eq!(value, "42".to_string());
95    }
96}