fix: don't panic in redis library on creating connection pool (#494)

This commit is contained in:
Kartikeya Hegde
2023-02-03 12:43:42 +05:30
committed by GitHub
parent 0441d5cdde
commit aa58d3466b
5 changed files with 30 additions and 18 deletions

View File

@ -589,7 +589,9 @@ mod tests {
#[tokio::test]
async fn test_consumer_group_create() {
let redis_conn = RedisConnectionPool::new(&RedisSettings::default()).await;
let redis_conn = RedisConnectionPool::new(&RedisSettings::default())
.await
.unwrap();
let result1 = redis_conn
.consumer_group_create("TEST1", "GTEST", &RedisEntryId::AutoGeneratedID)

View File

@ -52,4 +52,6 @@ pub enum RedisError {
NotFound,
#[error("Invalid RedisEntryId provided")]
InvalidRedisEntryId,
#[error("Failed to establish Redis connection")]
RedisConnectionError,
}

View File

@ -21,6 +21,8 @@ pub mod commands;
pub mod errors;
pub mod types;
use common_utils::errors::CustomResult;
use error_stack::{IntoReport, ResultExt};
use router_env::logger;
pub use self::{commands::*, types::*};
@ -28,17 +30,12 @@ pub use self::{commands::*, types::*};
pub struct RedisConnectionPool {
pub pool: fred::pool::RedisPool,
config: RedisConfig,
_join_handles: Vec<fred::types::ConnectHandle>,
join_handles: Vec<fred::types::ConnectHandle>,
}
impl RedisConnectionPool {
/// Create a new Redis connection
///
/// # Panics
///
/// Panics if a connection to Redis is not successful.
#[allow(clippy::expect_used)]
pub async fn new(conf: &RedisSettings) -> Self {
pub async fn new(conf: &RedisSettings) -> CustomResult<Self, errors::RedisError> {
let redis_connection_url = match conf.cluster_enabled {
// Fred relies on this format for specifying cluster where the host port is ignored & only query parameters are used for node addresses
// redis-cluster://username:password@host:port?node=bar.com:30002&node=baz.com:30003
@ -58,7 +55,9 @@ impl RedisConnectionPool {
),
};
let mut config = fred::types::RedisConfig::from_url(&redis_connection_url)
.expect("Invalid Redis connection URL");
.into_report()
.change_context(errors::RedisError::RedisConnectionError)?;
if !conf.use_legacy_version {
config.version = fred::types::RespVersion::RESP3;
}
@ -68,24 +67,27 @@ impl RedisConnectionPool {
conf.reconnect_delay,
);
let pool = fred::pool::RedisPool::new(config, conf.pool_size)
.expect("Unable to construct Redis pool");
.into_report()
.change_context(errors::RedisError::RedisConnectionError)?;
let _join_handles = pool.connect(Some(policy));
let join_handles = pool.connect(Some(policy));
pool.wait_for_connect()
.await
.expect("Error connecting to Redis");
.into_report()
.change_context(errors::RedisError::RedisConnectionError)?;
let config = RedisConfig::from(conf);
Self {
Ok(Self {
pool,
config,
_join_handles,
}
join_handles,
})
}
pub async fn close_connections(&mut self) {
self.pool.quit_pool().await;
for handle in self._join_handles.drain(..) {
for handle in self.join_handles.drain(..) {
match handle.await {
Ok(Ok(_)) => (),
Ok(Err(error)) => logger::error!(%error),