feat(router): add route to invalidate cache entry (#1100)

Co-authored-by: jeeva <jeeva.ramu@codurance.com>
Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com>
This commit is contained in:
Jeeva
2023-06-21 08:40:03 +01:00
committed by GitHub
parent 2b71d4d8c4
commit 21f2ccd47c
14 changed files with 271 additions and 43 deletions

View File

@ -26,7 +26,7 @@ use router_env::{instrument, logger, tracing};
use crate::{
errors,
types::{HsetnxReply, MsetnxReply, RedisEntryId, SetnxReply},
types::{DelReply, HsetnxReply, MsetnxReply, RedisEntryId, SetnxReply},
};
impl super::RedisConnectionPool {
@ -148,7 +148,7 @@ impl super::RedisConnectionPool {
}
#[instrument(level = "DEBUG", skip(self))]
pub async fn delete_key(&self, key: &str) -> CustomResult<(), errors::RedisError> {
pub async fn delete_key(&self, key: &str) -> CustomResult<DelReply, errors::RedisError> {
self.pool
.del(key)
.await
@ -664,30 +664,81 @@ impl super::RedisConnectionPool {
#[cfg(test)]
mod tests {
#![allow(clippy::unwrap_used)]
#![allow(clippy::expect_used, clippy::unwrap_used)]
use crate::{errors::RedisError, RedisConnectionPool, RedisEntryId, RedisSettings};
#[tokio::test]
async fn test_consumer_group_create() {
let redis_conn = RedisConnectionPool::new(&RedisSettings::default())
.await
.unwrap();
let is_invalid_redis_entry_error = tokio::task::spawn_blocking(move || {
futures::executor::block_on(async {
// Arrange
let redis_conn = RedisConnectionPool::new(&RedisSettings::default())
.await
.expect("failed to create redis connection pool");
let result1 = redis_conn
.consumer_group_create("TEST1", "GTEST", &RedisEntryId::AutoGeneratedID)
.await;
let result2 = redis_conn
.consumer_group_create("TEST3", "GTEST", &RedisEntryId::UndeliveredEntryID)
.await;
// Act
let result1 = redis_conn
.consumer_group_create("TEST1", "GTEST", &RedisEntryId::AutoGeneratedID)
.await;
assert!(matches!(
result1.unwrap_err().current_context(),
RedisError::InvalidRedisEntryId
));
assert!(matches!(
result2.unwrap_err().current_context(),
RedisError::InvalidRedisEntryId
));
let result2 = redis_conn
.consumer_group_create("TEST3", "GTEST", &RedisEntryId::UndeliveredEntryID)
.await;
// Assert Setup
*result1.unwrap_err().current_context() == RedisError::InvalidRedisEntryId
&& *result2.unwrap_err().current_context() == RedisError::InvalidRedisEntryId
})
})
.await
.expect("Spawn block failure");
assert!(is_invalid_redis_entry_error);
}
#[tokio::test]
async fn test_delete_existing_key_success() {
let is_success = tokio::task::spawn_blocking(move || {
futures::executor::block_on(async {
// Arrange
let pool = RedisConnectionPool::new(&RedisSettings::default())
.await
.expect("failed to create redis connection pool");
let _ = pool.set_key("key", "value".to_string()).await;
// Act
let result = pool.delete_key("key").await;
// Assert setup
result.is_ok()
})
})
.await
.expect("Spawn block failure");
assert!(is_success);
}
#[tokio::test]
async fn test_delete_non_existing_key_success() {
let is_success = tokio::task::spawn_blocking(move || {
futures::executor::block_on(async {
// Arrange
let pool = RedisConnectionPool::new(&RedisSettings::default())
.await
.expect("failed to create redis connection pool");
// Act
let result = pool.delete_key("key not exists").await;
// Assert Setup
result.is_ok()
})
})
.await
.expect("Spawn block failure");
assert!(is_success);
}
}

View File

@ -2,7 +2,7 @@
//! Errors specific to this custom redis interface
//!
#[derive(Debug, thiserror::Error)]
#[derive(Debug, thiserror::Error, PartialEq)]
pub enum RedisError {
#[error("Invalid Redis configuration: {0}")]
InvalidConfiguration(String),

View File

@ -226,3 +226,22 @@ impl From<StreamCapTrim> for fred::types::XCapTrim {
}
}
}
#[derive(Debug)]
pub enum DelReply {
KeyDeleted,
KeyNotDeleted, // Key not found
}
impl fred::types::FromRedis for DelReply {
fn from_value(value: fred::types::RedisValue) -> Result<Self, fred::error::RedisError> {
match value {
fred::types::RedisValue::Integer(1) => Ok(Self::KeyDeleted),
fred::types::RedisValue::Integer(0) => Ok(Self::KeyNotDeleted),
_ => Err(fred::error::RedisError::new(
fred::error::RedisErrorKind::Unknown,
"Unexpected del command reply",
)),
}
}
}