mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +08:00
feat(redis-interface): add redis interface command to set multiple the keys in redis and increment if the key already exists (#6827)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Nishant Joshi <nishant.joshi@juspay.in>
This commit is contained in:
@ -14,7 +14,7 @@ use common_utils::{
|
|||||||
use error_stack::{report, ResultExt};
|
use error_stack::{report, ResultExt};
|
||||||
use fred::{
|
use fred::{
|
||||||
interfaces::{HashesInterface, KeysInterface, ListInterface, SetsInterface, StreamsInterface},
|
interfaces::{HashesInterface, KeysInterface, ListInterface, SetsInterface, StreamsInterface},
|
||||||
prelude::RedisErrorKind,
|
prelude::{LuaInterface, RedisErrorKind},
|
||||||
types::{
|
types::{
|
||||||
Expiration, FromRedis, MultipleIDs, MultipleKeys, MultipleOrderedPairs, MultipleStrings,
|
Expiration, FromRedis, MultipleIDs, MultipleKeys, MultipleOrderedPairs, MultipleStrings,
|
||||||
MultipleValues, RedisKey, RedisMap, RedisValue, ScanType, Scanner, SetOptions, XCap,
|
MultipleValues, RedisKey, RedisMap, RedisValue, ScanType, Scanner, SetOptions, XCap,
|
||||||
@ -852,12 +852,31 @@ impl super::RedisConnectionPool {
|
|||||||
.await
|
.await
|
||||||
.change_context(errors::RedisError::ConsumerGroupClaimFailed)
|
.change_context(errors::RedisError::ConsumerGroupClaimFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "DEBUG", skip(self))]
|
||||||
|
pub async fn incr_keys_using_script<V>(
|
||||||
|
&self,
|
||||||
|
lua_script: &'static str,
|
||||||
|
key: Vec<String>,
|
||||||
|
values: V,
|
||||||
|
) -> CustomResult<(), errors::RedisError>
|
||||||
|
where
|
||||||
|
V: TryInto<MultipleValues> + Debug + Send + Sync,
|
||||||
|
V::Error: Into<fred::error::RedisError> + Send + Sync,
|
||||||
|
{
|
||||||
|
self.pool
|
||||||
|
.eval(lua_script, key, values)
|
||||||
|
.await
|
||||||
|
.change_context(errors::RedisError::IncrementHashFieldFailed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#![allow(clippy::expect_used, clippy::unwrap_used)]
|
#![allow(clippy::expect_used, clippy::unwrap_used)]
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{errors::RedisError, RedisConnectionPool, RedisEntryId, RedisSettings};
|
use crate::{errors::RedisError, RedisConnectionPool, RedisEntryId, RedisSettings};
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@ -911,7 +930,6 @@ mod tests {
|
|||||||
|
|
||||||
assert!(is_success);
|
assert!(is_success);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_delete_non_existing_key_success() {
|
async fn test_delete_non_existing_key_success() {
|
||||||
let is_success = tokio::task::spawn_blocking(move || {
|
let is_success = tokio::task::spawn_blocking(move || {
|
||||||
@ -930,6 +948,44 @@ mod tests {
|
|||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("Spawn block failure");
|
.expect("Spawn block failure");
|
||||||
|
assert!(is_success);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_setting_keys_using_scripts() {
|
||||||
|
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 lua_script = r#"
|
||||||
|
local results = {}
|
||||||
|
for i = 1, #KEYS do
|
||||||
|
results[i] = redis.call("INCRBY", KEYS[i], ARGV[i])
|
||||||
|
end
|
||||||
|
return results
|
||||||
|
"#;
|
||||||
|
let mut keys_and_values = HashMap::new();
|
||||||
|
for i in 0..10 {
|
||||||
|
keys_and_values.insert(format!("key{}", i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
let key = keys_and_values.keys().cloned().collect::<Vec<_>>();
|
||||||
|
let values = keys_and_values
|
||||||
|
.values()
|
||||||
|
.map(|val| val.to_string())
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
let result = pool.incr_keys_using_script(lua_script, key, values).await;
|
||||||
|
|
||||||
|
// Assert Setup
|
||||||
|
result.is_ok()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.expect("Spawn block failure");
|
||||||
|
|
||||||
assert!(is_success);
|
assert!(is_success);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user