Bug: Add redis commands required for success rate based routing




diff --git a/crates/redis_interface/src/commands.rs b/crates/redis_interface/src/commands.rs
index ccfeb3e5b12..9b76d8d9c81 100644
--- a/crates/redis_interface/src/commands.rs
+++ b/crates/redis_interface/src/commands.rs
@@ -15,7 +15,7 @@ use common_utils::{
 };
 use error_stack::{report, ResultExt};
 use fred::{
-    interfaces::{HashesInterface, KeysInterface, SetsInterface, StreamsInterface},
+    interfaces::{HashesInterface, KeysInterface, ListInterface, SetsInterface, StreamsInterface},
     prelude::RedisErrorKind,
     types::{
         Expiration, FromRedis, MultipleIDs, MultipleKeys, MultipleOrderedPairs, MultipleStrings,
@@ -371,6 +371,19 @@ impl super::RedisConnectionPool {
         Ok(hsetnx)
     }
 
+    #[instrument(level = "DEBUG", skip(self))]
+    pub async fn increment_field_in_hash(
+        &self,
+        key: &str,
+        field: &str,
+        increment: i64,
+    ) -> CustomResult<usize, errors::RedisError> {
+        self.pool
+            .hincrby(self.add_prefix(key), field, increment)
+            .await
+            .change_context(errors::RedisError::IncrementHashFieldFailed)
+    }
+
     #[instrument(level = "DEBUG", skip(self))]
     pub async fn hscan(
         &self,
@@ -630,6 +643,55 @@ impl super::RedisConnectionPool {
         })
     }
 
+    #[instrument(level = "DEBUG", skip(self))]
+    pub async fn append_elements_to_list<V>(
+        &self,
+        key: &str,
+        elements: V,
+    ) -> CustomResult<(), errors::RedisError>
+    where
+        V: TryInto<MultipleValues> + Debug + Send,
+        V::Error: Into<fred::error::RedisError> + Send,
+    {
+        self.pool
+            .rpush(self.add_prefix(key), elements)
+            .await
+            .change_context(errors::RedisError::AppendElementsToListFailed)
+    }
+
+    #[instrument(level = "DEBUG", skip(self))]
+    pub async fn get_list_elements(
+        &self,
+        key: &str,
+        start: i64,
+        stop: i64,
+    ) -> CustomResult<Vec<String>, errors::RedisError> {
+        self.pool
+            .lrange(self.add_prefix(key), start, stop)
+            .await
+            .change_context(errors::RedisError::GetListElementsFailed)
+    }
+
+    #[instrument(level = "DEBUG", skip(self))]
+    pub async fn get_list_length(&self, key: &str) -> CustomResult<usize, errors::RedisError> {
+        self.pool
+            .llen(self.add_prefix(key))
+            .await
+            .change_context(errors::RedisError::GetListLengthFailed)
+    }
+
+    #[instrument(level = "DEBUG", skip(self))]
+    pub async fn lpop_list_elements(
+        &self,
+        key: &str,
+        count: Option<usize>,
+    ) -> CustomResult<Vec<String>, errors::RedisError> {
+        self.pool
+            .lpop(self.add_prefix(key), count)
+            .await
+            .change_context(errors::RedisError::PopListElementsFailed)
+    }
+
     //                                              Consumer Group API
 
     #[instrument(level = "DEBUG", skip(self))]
diff --git a/crates/redis_interface/src/errors.rs b/crates/redis_interface/src/errors.rs
index cc7f8bdd21f..0e2a4b8d63b 100644
--- a/crates/redis_interface/src/errors.rs
+++ b/crates/redis_interface/src/errors.rs
@@ -68,4 +68,14 @@ pub enum RedisError {
     OnMessageError,
     #[error("Got an unknown result from redis")]
     UnknownResult,
+    #[error("Failed to append elements to list in Redis")]
+    AppendElementsToListFailed,
+    #[error("Failed to get list elements in Redis")]
+    GetListElementsFailed,
+    #[error("Failed to get length of list")]
+    GetListLengthFailed,
+    #[error("Failed to pop list elements in Redis")]
+    PopListElementsFailed,
+    #[error("Failed to increment hash field in Redis")]
+    IncrementHashFieldFailed,
 }

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
This PR adds the required redis commands for success rate based routing. Below are the added redis commands - 

*  ​​RPUSH (Push current block to aggregates list): Pushing an item to LIST
*  LRANGE (Get a list of buckets in aggregates): Access an item from LIST in a given range
*  LLEN (Check length of aggregates list): Get the length of LIST
*  LPOP (Remove first bucket in aggregates list): Remove first n elements from LIST
*  HINCRBY (Increment current_block's fields): Increment key of map

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
As this PR only adds the new redis commands and doesn't involve any existing code changes, basic sanity tests should suffice

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
