daoyi_cloud_common/redis/
mod.rs1use 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();
7pub 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}