use std::sync::Arc;
use std::time::Duration;
use ::redis::aio::ConnectionManager;
#[derive(Clone)]
pub struct RedisConnection {
pub(crate) client: ::redis::Client,
mgr: Arc<tokio::sync::OnceCell<ConnectionManager>>,
prefix: String,
}
impl RedisConnection {
pub fn open(url: &str) -> anyhow::Result<Self> {
Self::open_with_prefix(url, "noxy:")
}
pub fn open_with_prefix(url: &str, prefix: &str) -> anyhow::Result<Self> {
let client = ::redis::Client::open(url)?;
Ok(Self {
client,
mgr: Arc::new(tokio::sync::OnceCell::new()),
prefix: prefix.to_string(),
})
}
pub(crate) async fn get_connection(&self) -> Result<ConnectionManager, ::redis::RedisError> {
match tokio::time::timeout(
Duration::from_secs(2),
self.mgr
.get_or_try_init(|| ConnectionManager::new(self.client.clone())),
)
.await
{
Ok(result) => result.cloned(),
Err(_) => Err(::redis::RedisError::from((
::redis::ErrorKind::IoError,
"Redis connection timed out",
))),
}
}
pub(crate) fn prefixed_key(&self, namespace: &str, key: &str) -> String {
format!("{}{namespace}:{key}", self.prefix)
}
pub fn prefix(&self) -> &str {
&self.prefix
}
}