1use std::sync::OnceLock;
2use std::time::Duration;
3
4use redis::{cmd, Client, RedisError};
5use serde::Deserialize;
6
7use super::default_timeout;
8
9static REDIS: OnceLock<Client> = OnceLock::new();
10
11#[derive(Debug, Deserialize)]
12pub struct ClientConfig {
13 pub dsn: String,
14
15 #[serde(default = "default_timeout")]
16 pub timeout: Duration,
17}
18
19impl ClientConfig {
20 pub fn new(dsn: String) -> Self { Self { dsn, timeout: default_timeout() } }
21
22 pub fn build(&self) -> Result<Client, RedisError> {
23 let client = Client::open(self.dsn.clone())?;
24
25 let mut conn = client.get_connection_with_timeout(self.timeout)?;
26 let _ = cmd("PING").query::<String>(&mut conn)?;
27
28 Ok(client)
29 }
30}
31
32pub fn get_or_init_client(cfg: &ClientConfig) -> &'static Client {
34 REDIS.get_or_init(move || cfg.build().unwrap_or_else(|err| panic!("Redis 初始化失败. err: {}", err)))
35}
36
37pub fn get_client() -> Option<&'static Client> { REDIS.get() }
39
40pub fn must_get_client() -> &'static Client { get_client().unwrap_or_else(|| panic!("Redis连接未初始化")) }