mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
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:
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user