### Start HOTKEYS Tracking (Rust Example) Source: https://docs.rs/redis/latest/src/redis/commands/mod.rs.html Demonstrates how to start tracking hot keys using `HotkeysOptions` with CPU time and duration. Requires a standalone connection. ```rust let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_connection()?; // Start tracking hot keys by CPU time percentage for 60 seconds let opts = HotkeysOptions::new_with_cpu() .with_duration_secs(60); con.hotkeys_start(opts)?; ``` -------------------------------- ### HashMap Get Example Source: https://docs.rs/redis/latest/redis/struct.InfoDict.html Illustrates the basic usage of the get method on a HashMap to retrieve a value by key. Shows how to handle both existing and non-existing keys. ```rust use std::collections::HashMap; let mut map = HashMap::new(); map.insert(1, "a"); assert_eq!(map.get(&1), Some(&"a")); assert_eq!(map.get(&2), None); ``` -------------------------------- ### Basic Client Connection Example Source: https://docs.rs/redis/latest/redis/struct.Client.html Demonstrates how to open a Redis client and get a connection. Assumes a Redis server is running locally on the default port. ```rust let client = redis::Client::open("redis://127.0.0.1/").unwrap(); let con = client.get_connection().unwrap(); ``` -------------------------------- ### Example Usage of HotkeysCommands Source: https://docs.rs/redis/latest/redis/trait.HotkeysCommands.html Demonstrates how to start, perform operations, get metrics, and stop hot keys tracking on a standalone Redis connection. Requires `redis::HotkeysCommands` and `redis::HotkeysOptions` imports. ```rust use redis::{HotkeysCommands, HotkeysOptions}; let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_connection()?; // Start tracking hot keys by CPU time percentage for 60 seconds let opts = HotkeysOptions::new_with_cpu() .with_duration_secs(60); con.hotkeys_start(opts)?; // ... perform operations ... // Get hot keys metrics. `None` means no tracking session state is available // (e.g. reset or never started). if let Some(response) = con.hotkeys_get()? { if let Some(cpu_keys) = response.by_cpu_time_us.as_ref() { for entry in cpu_keys { println!("Key: {}, CPU time: {}", entry.key, entry.value); } } } // Stop tracking con.hotkeys_stop()?; ``` -------------------------------- ### HOTKEYS START Command Syntax Source: https://docs.rs/redis/latest/redis/trait.AsyncHotkeysCommands.html Illustrates the command syntax for starting hot keys tracking with various options. ```redis HOTKEYS START METRICS count [CPU] [NET] [COUNT k] [DURATION seconds] [SAMPLE ratio] [SLOTS count slot [slot ...]] ``` -------------------------------- ### Example Usage of SetOptions Source: https://docs.rs/redis/latest/redis/struct.SetOptions.html Demonstrates how to configure and use SetOptions for the Redis SET command, including conditional setting, value comparison, GET option, and expiration. ```rust use redis::{Commands, RedisResult, SetOptions, SetExpiry, ExistenceCheck, ValueComparison}; fn set_key_value( con: &mut redis::Connection, key: &str, value: &str, ) -> RedisResult> { let opts = SetOptions::default() .conditional_set(ExistenceCheck::NX) .value_comparison(ValueComparison::ifeq("old_value")) .get(true) .with_expiration(SetExpiry::EX(60)); con.set_options(key, value, opts) } ``` -------------------------------- ### Example Usage of FlushAllOptions Source: https://docs.rs/redis/latest/redis/struct.FlushAllOptions.html Demonstrates how to create and use FlushAllOptions with the flushall_options command. This example sets the blocking option to true. ```rust use redis::{Commands, RedisResult, FlushAllOptions}; fn flushall_sync( con: &mut redis::Connection, ) -> RedisResult<()> { let opts = FlushAllOptions{blocking: true}; con.flushall_options(&opts) } ``` -------------------------------- ### InfoDict Usage Example Source: https://docs.rs/redis/latest/src/redis/types.rs.html Demonstrates how to retrieve Redis server information using the `INFO` command and parse it into an `InfoDict`. The example shows how to query for specific information like the server's role. ```rust /// This type provides convenient access to key/value data returned by /// the "INFO" command. It acts like a regular mapping but also has /// a convenience method `get` which can return data in the appropriate /// type. /// /// For instance this can be used to query the server for the role it's /// in (master, slave) etc: /// /// ```rust,no_run /// # fn do_something() -> redis::RedisResult<()> { // Added fn wrapper for doctest /// # let client = redis::Client::open("redis://127.0.0.1/").unwrap(); /// # let mut con = client.get_connection().unwrap(); /// let info : redis::InfoDict = redis::cmd("INFO").query(&mut con)?; /// let role : Option = info.get("role"); /// # Ok(()) /// # } /// ``` ``` -------------------------------- ### Pipeline with High-Level Commands Source: https://docs.rs/redis/latest/index.html This example shows how to use high-level client methods (like `set` and `get`) within a pipeline, including atomic execution. ```rust let (k1, k2) : (i32, i32) = redis::pipe() .atomic() .set("key_1", 42).ignore() .set("key_2", 43).ignore() .get("key_1") .get("key_2").query(&mut con)?; ``` -------------------------------- ### Get HOTKEYS Metrics (Rust Example) Source: https://docs.rs/redis/latest/src/redis/commands/mod.rs.html Shows how to retrieve hot keys metrics. Returns `Some(response)` if tracking state is available, otherwise `None`. ```rust // Get hot keys metrics. `None` means no tracking session state is available // (e.g. reset or never started). if let Some(response) = con.hotkeys_get()? { if let Some(cpu_keys) = response.by_cpu_time_us.as_ref() { for entry in cpu_keys { println!("Key: {}, CPU time: {}", entry.key, entry.value); } } } ``` -------------------------------- ### Start HOTKEYS Tracking Implementation Source: https://docs.rs/redis/latest/src/redis/commands/mod.rs.html Rust implementation for the `hotkeys_start` command, which sends `HOTKEYS START` with provided options. ```rust fn hotkeys_start(&mut self, opts: hotkeys::HotkeysOptions) -> RedisResult<()> where Self: Sized, { cmd("HOTKEYS").arg("START").arg(opts).query(self) } ``` -------------------------------- ### Setup Redis Connection Pipeline Source: https://docs.rs/redis/latest/src/redis/connection.rs.html Prepares a pipeline for connection setup, including authentication and database selection. It supports RESP3 HELLO and RESP2 AUTH commands. ```rust pub(crate) fn connection_setup_pipeline( connection_info: &RedisConnectionInfo, check_username: bool, #[cfg(feature = "cache-aio")] cache_config: Option, ) -> (crate::Pipeline, ConnectionSetupComponents) { let mut pipeline = pipe(); let (authenticate_with_resp3_cmd_index, authenticate_with_resp2_cmd_index) = if connection_info.protocol.supports_resp3() { pipeline.add_command(resp3_hello(connection_info)); (Some(0), None) } else if let Some(password) = connection_info.password.as_ref() { pipeline.add_command(authenticate_cmd( check_username.then(|| connection_info.username()).flatten(), password, )); (None, Some(0)) } else { (None, None) }; let select_db_cmd_index = (connection_info.db != 0) .then(|| pipeline.len()) .inspect(|_| { pipeline.cmd("SELECT").arg(connection_info.db); }); #[cfg(feature = "cache-aio")] let cache_cmd_index = cache_config.map(|cache_config| { pipeline.cmd("CLIENT").arg("TRACKING").arg("ON"); match cache_config.mode { crate::caching::CacheMode::All => {} crate::caching::CacheMode::OptIn => { pipeline.arg("OPTIN"); } } pipeline.len() - 1 }); // result is ignored, as per the command's instructions. // https://redis.io/commands/client-setinfo/ if !connection_info.skip_set_lib_name { pipeline .cmd("CLIENT") .arg("SETINFO") .arg("LIB-NAME") .arg( connection_info .lib_name .as_ref() .map_or(DEFAULT_CLIENT_SETINFO_LIB_NAME, ArcStr::as_str), ) .ignore(); pipeline .cmd("CLIENT") .arg("SETINFO") .arg("LIB-VER") .arg( connection_info .lib_ver .as_ref() ); } (pipeline, ConnectionSetupComponents { resp3_auth_cmd_idx: authenticate_with_resp3_cmd_index, resp2_auth_cmd_idx: authenticate_with_resp2_cmd_index, select_cmd_idx: select_db_cmd_index, #[cfg(feature = "cache-aio")] cache_cmd_idx: cache_cmd_index }) } ``` -------------------------------- ### Async Redis Command Example Source: https://docs.rs/redis/latest/src/redis/commands/macros.rs.html Demonstrates how to set a key-value pair and retrieve it asynchronously using `AsyncCommands`. This example shows the transformation from a raw command to a typed method call. ```rust use redis::AsyncCommands; # async fn do_something() -> redis::RedisResult<()> { use redis::Commands; let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_multiplexed_async_connection().await?; let _: () = con.set("my_key", 42i32).await?; assert_eq!(con.get("my_key").await, Ok(42i32)); # Ok(()) # } ``` -------------------------------- ### Execute Connection Pipeline and Check Setup Source: https://docs.rs/redis/latest/src/redis/connection.rs.html Executes a packed pipeline of Redis commands and then checks the connection setup results using `check_connection_setup`. Returns `AuthResult` indicating the outcome. ```rust fn execute_connection_pipeline( rv: &mut Connection, (pipeline, instructions): (crate::Pipeline, ConnectionSetupComponents), ) -> RedisResult { if pipeline.is_empty() { return Ok(AuthResult::Succeeded); } let results = rv.req_packed_commands(&pipeline.get_packed_pipeline(), 0, pipeline.len())?; check_connection_setup(results, instructions) } ``` -------------------------------- ### Start Hotkeys Tracking (Async) Source: https://docs.rs/redis/latest/src/redis/commands/mod.rs.html Starts tracking hot keys with specified options. This is an asynchronous operation. Requires Redis 8.6.0+. ```rust fn hotkeys_start( &mut self, opts: hotkeys::HotkeysOptions, ) -> crate::types::RedisFuture<'_, ()> { Box::pin(async move { cmd("HOTKEYS") .arg("START") .arg(opts) .query_async(self) .await }) } ``` -------------------------------- ### Redis Cluster Pipelining Example Source: https://docs.rs/redis/latest/src/redis/cluster_handling/sync_connection/mod.rs.html Shows how to use pipelining with Redis Cluster to send multiple commands efficiently. This example uses `cluster_pipe` to queue commands like RPUSH, LTRIM, and EXPIRE. ```rust use redis::TypedCommands; use redis::cluster::{cluster_pipe, ClusterClient}; let nodes = vec!["redis://127.0.0.1:6379/", "redis://127.0.0.1:6378/", "redis://127.0.0.1:6377/"]; let client = ClusterClient::new(nodes).unwrap(); let mut connection = client.get_connection().unwrap(); let key = "test"; cluster_pipe() .rpush(key, "123").ignore() .ltrim(key, -10, -1).ignore() .expire(key, 60).ignore() .exec(&mut connection).unwrap(); ``` -------------------------------- ### LRANGE Command Example Source: https://docs.rs/redis/latest/redis/trait.Commands.html Retrieves a range of elements from a list. Specify start and stop indices to get a sub-list. ```rust fn lrange<'a, K: ToSingleRedisArg, RV: FromRedisValue>( &mut self, key: K, start: isize, stop: isize, ) -> RedisResult { ... } ``` -------------------------------- ### Creating HotkeysOptions with Network Tracking Source: https://docs.rs/redis/latest/redis/struct.HotkeysOptions.html Illustrates how to initialize HotkeysOptions for tracking hotkeys based on network bytes percentage. It also shows how to combine network and CPU tracking. ```rust use redis::HotkeysOptions; // Track hotkeys by network bytes let opts = HotkeysOptions::new_with_net(); // Track by both network and CPU let opts = HotkeysOptions::new_with_net().and_cpu(); ``` -------------------------------- ### Generic SET and GET using redis::cmd Source: https://docs.rs/redis/latest/redis/trait.Commands.html Illustrates the traditional method of executing SET and GET commands using the generic `redis::cmd` function. This is shown for comparison with the `Commands` trait. ```rust let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_connection()?; redis::cmd("SET").arg("my_key").arg(42).exec(&mut con).unwrap(); assert_eq!(redis::cmd("GET").arg("my_key").query(&mut con), Ok(42)); ``` -------------------------------- ### Get Message Range with XRANGE Source: https://docs.rs/redis/latest/redis/trait.AsyncTypedCommands.html Returns a range of messages from a stream key. Use `-` for the start and `+` for the end to get all messages. Requires the `streams` crate feature. ```redis XRANGE key start end ``` -------------------------------- ### Example Usage of HotkeysOptions Source: https://docs.rs/redis/latest/redis/struct.HotkeysOptions.html Demonstrates how to create and configure HotkeysOptions for tracking hotkeys by both CPU and network usage over a specified duration. ```rust use redis::{HotkeysOptions, HotkeysCommands}; let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_connection()?; // Track hotkeys by both CPU and network usage for 60 seconds let opts = HotkeysOptions::new_with_cpu() .and_net() .with_duration_secs(60); con.hotkeys_start(opts)?; ``` -------------------------------- ### connection_setup_pipeline Source: https://docs.rs/redis/latest/src/redis/connection.rs.html Creates a pipeline for initial connection setup commands, including authentication, database selection, and client info setting. ```APIDOC ## connection_setup_pipeline ### Description Creates a pipeline for initial connection setup commands, including authentication, database selection, and client info setting. This is used internally to prepare the connection before it's returned to the user. ### Function Signature `pub(crate) fn connection_setup_pipeline(connection_info: &RedisConnectionInfo, check_username: bool, #[cfg(feature = "cache-aio")] cache_config: Option) -> (crate::Pipeline, ConnectionSetupComponents)` ### Parameters - **connection_info** (`&RedisConnectionInfo`) - Connection details for the Redis server. - **check_username** (`bool`) - Whether to check for a username during authentication. - **cache_config** (`Option`) - Optional cache configuration if the `cache-aio` feature is enabled. ### Returns - `(crate::Pipeline, ConnectionSetupComponents)` - A tuple containing the prepared pipeline and connection setup components. ``` -------------------------------- ### Get a Range of Messages from a Stream Source: https://docs.rs/redis/latest/redis/struct.Pipeline.html Retrieves a specified range of messages from a stream by key. Use '-' for the start and '+' for the end to get all messages. Available only with the `streams` crate feature. ```rust pub fn xrange<'a, K: ToRedisArgs, S: ToRedisArgs, E: ToRedisArgs>( &mut self, key: K, start: S, end: E, ) -> &mut Self ``` -------------------------------- ### Creating HotkeysOptions with CPU Tracking Source: https://docs.rs/redis/latest/redis/struct.HotkeysOptions.html Shows how to initialize HotkeysOptions to track hotkeys based on CPU time percentage. It also includes an example of combining CPU and network tracking. ```rust use redis::HotkeysOptions; // Track hotkeys by CPU time let opts = HotkeysOptions::new_with_cpu(); // Track by both CPU and network let opts = HotkeysOptions::new_with_cpu().and_net(); ``` -------------------------------- ### SCARD Command Example Source: https://docs.rs/redis/latest/redis/trait.Commands.html Returns the number of members in a set. Use this to get the size of a set. ```rust fn scard<'a, K: ToSingleRedisArg, RV: FromRedisValue>( &mut self, key: K, ) -> RedisResult { ... } ``` -------------------------------- ### Compile-time Check for Multiple Values in GET Command Source: https://docs.rs/redis/latest/index.html This example demonstrates how the Redis Rust client now enforces compilation failures for commands like `get` when provided with multiple values, ensuring they serialize into single Redis values. ```rust use redis::Commands; fn main() -> redis::RedisResult<()> { let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_connection()?; // `get` should fail compilation, because it receives multiple values _ = con.get(["foo","bar"]); Ok(()) } ``` -------------------------------- ### Redis Pub/Sub Example Source: https://docs.rs/redis/latest/src/redis/connection.rs.html Demonstrates how to subscribe to channels, receive messages, and process them in a loop. ```rust # fn do_something() -> redis::RedisResult<()> { let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_connection()?; let mut pubsub = con.as_pubsub(); pubsub.subscribe("channel_1")?; pubsub.subscribe("channel_2")?; loop { let msg = pubsub.get_message()?; let payload : String = msg.get_payload()?; println!("channel '{}': {}", msg.get_channel_name(), payload); } # } ``` -------------------------------- ### Get a Substring of a String Value Source: https://docs.rs/redis/latest/redis/trait.AsyncTypedCommands.html Retrieves a portion of the string value stored at a key, specified by start and end offsets. ```rust fn getrange<'a, K: ToSingleRedisArg + Send + Sync + 'a>( &'a mut self, key: K, from: isize, to: isize, ) -> RedisFuture<'a, String> { ... } ``` -------------------------------- ### Get a Range of a String Value Source: https://docs.rs/redis/latest/redis/trait.TypedCommands.html Retrieves a sub-string of the value stored at a key, specified by start and end offsets. Offsets are 0-based. ```rust pub trait TypedCommands: ConnectionLike + Sized { fn getrange<'a, K: ToSingleRedisArg + Send + Sync + 'a>( &'a mut self, key: K, from: isize, to: isize, ) -> RedisResult { ... } ``` -------------------------------- ### PubSub Example Usage Source: https://docs.rs/redis/latest/redis/struct.PubSub.html Demonstrates how to create a PubSub connection, subscribe to channels, and continuously listen for messages. ```APIDOC ### Example ```rust let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_connection()?; let mut pubsub = con.as_pubsub(); pubsub.subscribe("channel_1")?; pubsub.subscribe("channel_2")?; loop { let msg = pubsub.get_message()?; let payload : String = msg.get_payload()?; println!("channel '{}': {}", msg.get_channel_name(), payload); } ``` ``` -------------------------------- ### Creating and Using StreamConfigOptions Source: https://docs.rs/redis/latest/redis/streams/struct.StreamConfigOptions.html Demonstrates how to create StreamConfigOptions using constructor methods and apply them to the xcfgset command. Shows two ways to initialize options: by idempotency duration first, or by max size first. ```rust use redis::{Commands, streams::StreamConfigOptions}; // Create with idempotency duration in seconds, optionally add maxsize let opts1 = StreamConfigOptions::with_idempotency_seconds(300) .unwrap() .idempotency_maxsize(1000) .unwrap(); let _: String = con.xcfgset("key", &opts1).unwrap(); // Or create with maxsize only and optionally add idempotency duration in seconds let opts2 = StreamConfigOptions::with_idempotency_maxsize(500) .unwrap() .idempotency_seconds(300) .unwrap(); let _: String = con.xcfgset("key", &opts2).unwrap(); ``` -------------------------------- ### Get JSON Array Elements within Range Source: https://docs.rs/redis/latest/redis/trait.JsonAsyncCommands.html Retrieves JSON values from an array within a specified start and stop index range. ```rust fn json_arr_index_ss<'a, K: ToSingleRedisArg + Send + Sync + 'a, P: ToSingleRedisArg + Send + Sync + 'a, V: Serialize + Send + Sync + 'a, RV>( &'a mut self, key: K, path: P, value: &'a V, start: &'a isize, stop: &'a isize, ) -> RedisFuture<'a, RV> where RV: FromRedisValue { ... } ``` -------------------------------- ### Iterating Over Ok Values Source: https://docs.rs/redis/latest/redis/type.RedisResult.html Provides an example of using `iter` to get an iterator that yields the contained value if the Result is Ok, and is empty otherwise. ```Rust let x: Result = Ok(7); assert_eq!(x.iter().next(), Some(&7)); let x: Result = Err("nothing!"); assert_eq!(x.iter().next(), None); ``` -------------------------------- ### HashMap Get Key-Value Example Source: https://docs.rs/redis/latest/redis/struct.InfoDict.html Demonstrates retrieving both the key and value associated with a given key from a HashMap. Handles cases where the key is not present. ```rust use std::collections::HashMap; let mut map = HashMap::new(); map.insert(1, "a"); assert_eq!(map.get_key_value(&1), Some((&1, &"a"))); assert_eq!(map.get_key_value(&2), None); ``` -------------------------------- ### Hotkeys Options with Network and CPU Metrics Source: https://docs.rs/redis/latest/src/redis/commands/hotkeys.rs.html Demonstrates creating HotkeysOptions with network and then CPU metrics. The order of CPU and NET in the arguments is fixed. ```rust let opts = HotkeysOptions::new_with_net().and_cpu(); assert_eq!(opts.num_of_args(), 4); // METRICS 2 CPU NET let args = opts.to_redis_args(); assert_eq!(args.len(), 4); assert_eq!(args[0], b"METRICS"); assert_eq!(args[1], b"2"); // CPU comes before NET in serialization order assert_eq!(args[2], b"CPU"); assert_eq!(args[3], b"NET"); ``` -------------------------------- ### Example Usage of CopyOptions Source: https://docs.rs/redis/latest/redis/struct.CopyOptions.html Demonstrates how to create and use CopyOptions to copy a Redis key to another database, with the option to replace it if it already exists. ```rust use redis::{Commands, RedisResult, CopyOptions, SetExpiry, ExistenceCheck}; fn copy_value( con: &mut redis::Connection, old: &str, new: &str, ) -> RedisResult> { let opts = CopyOptions::default() .db("my_other_db") .replace(true); con.copy(old, new, opts) } ``` -------------------------------- ### Building a Redis Command with Simple Arguments Source: https://docs.rs/redis/latest/src/redis/cmd.rs.html Illustrates how to construct a Redis command with various simple arguments, including strings, numbers, and byte slices. It also shows how to get the packed command representation and verify the arguments. ```rust let args: &[&[u8]] = &[b"phone", b"barz"]; let mut cmd = cmd("key"); cmd.write_arg_fmt("value"); cmd.arg(42).arg(args); let packed_command = cmd.get_packed_command(); assert_eq!(cmd_len(&cmd), packed_command.len()); assert_eq!( packed_command, b"*5\r\n$3\r\nkey\r\n$5\r\nvalue\r\n$2\r\n42\r\n$5\r\nphone\r\n$4\r\nbarz\r\n", "{}", String::from_utf8(packed_command.clone()).unwrap() ); let args_vec: Vec<&[u8]> = vec![b"key", b"value", b"42", b"phone", b"barz"]; let args_vec: Vec<_> = args_vec.into_iter().map(Arg::Simple).collect(); assert_eq!(cmd.args_iter().collect::>(), args_vec); ``` -------------------------------- ### hotkeys_start Source: https://docs.rs/redis/latest/redis/aio/struct.MultiplexedConnection.html Start tracking hot keys with the given options. ```APIDOC ## hotkeys_start ### Description Start tracking hot keys with the given options. ### Method `fn hotkeys_start(&mut self, opts: HotkeysOptions) -> RedisFuture<'_, ()>` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None provided in source. ### Response #### Success Response Returns `()` on successful start. #### Response Example None explicitly shown, success is indicated by the absence of an error. ``` -------------------------------- ### Get a Range of Bytes/Substring from a Key Source: https://docs.rs/redis/latest/redis/struct.Client.html Retrieves a portion of the value stored in a key, specified by start and end offsets. Handles negative offsets from the end of the value. ```rust fn getrange<'a, K: ToSingleRedisArg, RV: FromRedisValue>( &mut self, key: K, from: isize, to: isize, ) -> RedisResult ``` -------------------------------- ### Asynchronous JSON Get Example Source: https://docs.rs/redis/latest/src/redis/commands/json.rs.html Demonstrates fetching JSON data asynchronously. Note that all results are wrapped in square brackets and may require deserialization into a Vec. ```rust /// assert_eq!(con.json_get("my_key", "$").await, Ok(String::from(r#"[{"item":42}]"#))); /// assert_eq!(con.json_get("my_key", "$.item").await, Ok(String::from(r#"[42]"#))); /// # Ok(()) } ``` -------------------------------- ### Example Usage: Subscribe and Unsubscribe Source: https://docs.rs/redis/latest/src/redis/cluster_handling/async_connection/mod.rs.html Demonstrates how to set up a Redis client with RESP3 protocol and a push sender, then subscribe and unsubscribe from channels. ```rust /// ```rust,no_run /// # async fn func() -> redis::RedisResult<()> { /// let nodes = vec!["redis://127.0.0.1/protocol=3"]; /// let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel(); /// let client = redis::cluster::ClusterClientBuilder::new(nodes) /// .use_protocol(redis::ProtocolVersion::RESP3) /// .push_sender(tx).build()?; /// let mut con = client.get_async_connection().await?; /// con.subscribe(&["channel_1", "channel_2"]).await?; /// con.unsubscribe(&["channel_1", "channel_2"]).await?; /// # Ok(()) } /// ``` ``` -------------------------------- ### Redis Cluster Pipeline Creation and Execution Example Source: https://docs.rs/redis/latest/src/redis/cluster_handling/sync_connection/pipeline.rs.html Demonstrates how to create a cluster pipeline, add commands with and without ignoring their results, and then execute the pipeline to retrieve specific results. Use this to batch commands for efficiency in a Redis cluster. ```rust use super::ClusterConnection; use crate::RedisError; use crate::cmd::{Cmd, cmd}; use crate::errors::ErrorKind; use crate::types::{FromRedisValue, HashSet, RedisResult, ToRedisArgs, Value, from_redis_value}; pub(crate) const UNROUTABLE_ERROR: (ErrorKind, &str) = ( ErrorKind::Client, "This command cannot be safely routed in cluster mode", ); fn is_illegal_cmd(cmd: &str) -> bool { matches!( cmd, "BGREWRITEAOF" | "BGSAVE" | "BITOP" | "BRPOPLPUSH" | // All commands that start with "CLIENT" "CLIENT" | "CLIENT GETNAME" | "CLIENT KILL" | "CLIENT LIST" | "CLIENT SETNAME" | // All commands that start with "CONFIG" "CONFIG" | "CONFIG GET" | "CONFIG RESETSTAT" | "CONFIG REWRITE" | "CONFIG SET" | "DBSIZE" | "ECHO" | "FLUSHALL" | "FLUSHDB" | "INFO" | "KEYS" | "LASTSAVE" | "MGET" | "MOVE" | "MSET" | "MSETNX" | "MSETEX" | "PING" | "PUBLISH" | "RANDOMKEY" | "RENAME" | "RENAMENX" | "RPOPLPUSH" | "SAVE" | "SCAN" | // All commands that start with "SCRIPT" "SCRIPT" | "SCRIPT EXISTS" | "SCRIPT FLUSH" | "SCRIPT KILL" | "SCRIPT LOAD" | "SDIFF" | "SDIFFSTORE" | // All commands that start with "SENTINEL" "SENTINEL" | "SENTINEL GET MASTER ADDR BY NAME" | "SENTINEL MASTER" | "SENTINEL MASTERS" | "SENTINEL MONITOR" | "SENTINEL REMOVE" | "SENTINEL SENTINELS" | "SENTINEL SET" | "SENTINEL SLAVES" | "SHUTDOWN" | "SINTER" | "SINTERSTORE" | "SLAVEOF" | // All commands that start with "SLOWLOG" "SLOWLOG" | "SLOWLOG GET" | "SLOWLOG LEN" | "SLOWLOG RESET" | "SMOVE" | "SORT" | "SUNION" | "SUNIONSTORE" | "TIME" ) } /// Represents a Redis Cluster command pipeline. #[derive(Clone)] pub struct ClusterPipeline { commands: Vec, ignored_commands: HashSet, ignore_errors: bool, } /// A cluster pipeline is almost identical to a normal [Pipeline](crate::pipeline::Pipeline), with two exceptions: /// * It does not support transactions /// * The following commands can not be used in a cluster pipeline: /// ```text /// BGREWRITEAOF, BGSAVE, BITOP, BRPOPLPUSH /// CLIENT GETNAME, CLIENT KILL, CLIENT LIST, CLIENT SETNAME, CONFIG GET, /// CONFIG RESETSTAT, CONFIG REWRITE, CONFIG SET /// DBSIZE /// ECHO, EVALSHA /// FLUSHALL, FLUSHDB /// INFO /// KEYS /// LASTSAVE /// MGET, MOVE, MSET, MSETNX, MSETEX /// PING, PUBLISH /// RANDOMKEY, RENAME, RENAMENX, RPOPLPUSH /// SAVE, SCAN, SCRIPT EXISTS, SCRIPT FLUSH, SCRIPT KILL, SCRIPT LOAD, SDIFF, SDIFFSTORE, /// SENTINEL GET MASTER ADDR BY NAME, SENTINEL MASTER, SENTINEL MASTERS, SENTINEL MONITOR, /// SENTINEL REMOVE, SENTINEL SENTINELS, SENTINEL SET, SENTINEL SLAVES, SHUTDOWN, SINTER, /// SINTERSTORE, SLAVEOF, SLOWLOG GET, SLOWLOG LEN, SLOWLOG RESET, SMOVE, SORT, SUNION, SUNIONSTORE /// TIME /// ``` impl ClusterPipeline { /// Create an empty pipeline. pub fn new() -> ClusterPipeline { Self::with_capacity(0) } /// Creates an empty pipeline with pre-allocated capacity. pub fn with_capacity(capacity: usize) -> ClusterPipeline { ClusterPipeline { commands: Vec::with_capacity(capacity), ignored_commands: HashSet::new(), ignore_errors: false, } } pub(crate) fn commands(&self) -> &Vec { &self.commands } /// Executes the pipeline and fetches the return values: /// /// ```rust,no_run /// # let nodes = vec!["redis://127.0.0.1:6379/"]; /// # let client = redis::cluster::ClusterClient::new(nodes).unwrap(); /// # let mut con = client.get_connection().unwrap(); /// let mut pipe = redis::cluster::cluster_pipe(); /// let (k1, k2) : (i32, i32) = pipe /// .cmd("SET").arg("key_1").arg(42).ignore() /// .cmd("SET").arg("key_2").arg(43).ignore() /// .cmd("GET").arg("key_1") /// .cmd("GET").arg("key_2").query(&mut con).unwrap(); /// ``` #[inline] pub fn query(&self, con: &mut ClusterConnection) -> RedisResult { for cmd in &self.commands { let cmd_name = std::str::from_utf8(cmd.arg_idx(0).unwrap_or(b"")) .unwrap_or("") .trim() .to_ascii_uppercase(); if is_illegal_cmd(&cmd_name) { fail!( ( UNROUTABLE_ERROR.0, UNROUTABLE_ERROR.1, format!("Command '{}' can't be executed in a cluster pipeline.", cmd_name) ) ) } } if self.commands.is_empty() { ``` -------------------------------- ### Connect to Redis Sentinel and get Master/Replica Clients Source: https://docs.rs/redis/latest/src/redis/sentinel.rs.html Build a Sentinel connection and obtain clients for master and replica nodes. This is useful for basic high-availability setups. ```rust use redis::TypedCommands; use redis::sentinel::Sentinel; let nodes = vec!["redis://127.0.0.1:6379/", "redis://127.0.0.1:6378/", "redis://127.0.0.1:6377/"]; let mut sentinel = Sentinel::build(nodes).unwrap(); let mut master = sentinel.master_for("master_name", None).unwrap().get_connection().unwrap(); let mut replica = sentinel.replica_for("master_name", None).unwrap().get_connection().unwrap(); master.set("test", "test_data").unwrap(); let rv = replica.get("test").unwrap().unwrap(); assert_eq!(rv, "test_data"); ``` -------------------------------- ### Get a Range of a String Source: https://docs.rs/redis/latest/redis/trait.AsyncCommands.html Retrieves a sub-string of a string value stored at a key, using start and end offsets asynchronously. Requires `key` to implement `ToSingleRedisArg`, and `RV` to implement `FromRedisValue`. ```rust fn getrange<'a, K: ToSingleRedisArg + Send + Sync + 'a, RV>( &'a mut self, key: K, from: isize, to: isize, ) -> RedisFuture<'a, RV> where RV: FromRedisValue { ... } ``` -------------------------------- ### hotkeys_start Source: https://docs.rs/redis/latest/redis/trait.AsyncHotkeysCommands.html Start tracking hot keys with the given options. This command is available on crate feature `aio` only. ```APIDOC ## hotkeys_start ### Description Start tracking hot keys with the given options. ### Method `hotkeys_start` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **opts** (HotkeysOptions) - Required - Options for starting hotkeys tracking. ### Request Example ```rust // Example usage (assuming `connection` is an async connection object) // let opts = HotkeysOptions::new().count(100).duration(60); // connection.hotkeys_start(opts).await; ``` ### Response #### Success Response - **()** - Indicates the command was successful. #### Response Example ```rust // No specific response body for success, indicates completion. ``` ### Redis Command ``` HOTKEYS START METRICS count [CPU] [NET] [COUNT k] [DURATION seconds] [SAMPLE ratio] [SLOTS count slot [slot ...]] ``` ``` -------------------------------- ### Get a range of stream elements with a count limit Source: https://docs.rs/redis/latest/src/redis/commands/mod.rs.html Retrieves a specified number of elements from a stream within a given range (end to start) in reverse order. Useful for paginating stream data. ```rust #[cfg(feature = "streams")] #[cfg_attr(docsrs, doc(cfg(feature = "streams")))] fn xrevrange_count( key: K, end: E, start: S, count: C ) -> (streams::StreamRangeReply) { cmd("XREVRANGE") .arg(key) .arg(end) .arg(start) .arg("COUNT") .arg(count) .take() } ``` -------------------------------- ### hotkeys_start (async) Source: https://docs.rs/redis/latest/src/redis/commands/mod.rs.html Starts tracking hot keys with the specified options. This command is stateful and node-local, requiring session affinity. It is only implemented for standalone connection types and not for cluster clients. ```APIDOC ## hotkeys_start ### Description Start tracking hot keys with the given options. ### Method ```rust fn hotkeys_start(&mut self, opts: hotkeys::HotkeysOptions) -> crate::types::RedisFuture<'_, ()> ``` ### Endpoint ```text HOTKEYS START METRICS count [CPU] [NET] [COUNT k] [DURATION seconds] [SAMPLE ratio] [SLOTS count slot [slot ...]] ``` ### Parameters #### Request Body - **opts** (hotkeys::HotkeysOptions) - Required - Options for tracking hot keys. ### Related Documentation [Redis Docs](https://redis.io/commands/hotkeys-start/) ``` -------------------------------- ### Get Message Range from Stream Source: https://docs.rs/redis/latest/redis/cluster/struct.ClusterPipeline.html Retrieves a range of messages from a stream key, specified by start and end IDs. Use '-' for the earliest message and '+' for the latest. This command returns a `StreamRangeReply`. ```rust pub fn xrange<'a, K: ToRedisArgs, S: ToRedisArgs, E: ToRedisArgs>( &mut self, key: K, start: S, end: E, ) -> &mut Self ``` ```redis XRANGE key start end ``` -------------------------------- ### Get Pending Message Count Over a Range Source: https://docs.rs/redis/latest/redis/cluster/struct.ClusterPipeline.html Returns a list of all pending messages within a specified range (start, stop, count) for a stream and group. This method is suitable for paginating pending messages. ```rust pub fn xpending_count<'a, K: ToRedisArgs, G: ToRedisArgs, S: ToRedisArgs, E: ToRedisArgs, C: ToRedisArgs>( &mut self, key: K, group: G, start: S, end: E, count: C, ) -> &mut Self ``` ```redis XPENDING ``` -------------------------------- ### Async Transaction Example Source: https://docs.rs/redis/latest/redis/aio/fn.transaction_async.html Demonstrates how to use `transaction_async` to atomically increment a Redis counter. The closure reads the current value, prepares a pipeline to set the new value and get it back, and returns the result. ```rust use redis::{AsyncCommands, RedisResult, pipe}; async fn increment(con: redis::aio::MultiplexedConnection) -> RedisResult { let key = "my_counter"; redis::aio::transaction_async(con, &[key], |mut con, mut pipe| async move { // Read the current value first let val: isize = con.get(key).await?; // Build the pipeline and execute it atomically (MULTI/EXEC are added automatically) pipe.set(key, val + 1) .ignore() .get(key) .query_async(&mut con) .await }) .await } ``` -------------------------------- ### Redis Stream Range Commands Source: https://docs.rs/redis/latest/redis/trait.TypedCommands.html These methods retrieve a range of elements from a Redis stream. They support filtering by start and end IDs, and optionally limiting the count of returned elements. Use `xrange_all` to get all elements. ```rust fn xrange<'a, K: ToRedisArgs + Send + Sync + 'a, S: ToRedisArgs + Send + Sync + 'a, E: ToRedisArgs + Send + Sync + 'a>( &'a mut self, key: K, start: S, end: E,) -> RedisResult { ... } ``` ```rust fn xrange_all<'a, K: ToRedisArgs + Send + Sync + 'a>( &'a mut self, key: K,) -> RedisResult { ... } ``` ```rust fn xrange_count<'a, K: ToRedisArgs + Send + Sync + 'a, S: ToRedisArgs + Send + Sync + 'a, E: ToRedisArgs + Send + Sync + 'a, C: ToRedisArgs + Send + Sync + 'a>( &'a mut self, key: K, start: S, end: E, count: C,) -> RedisResult { ... } ``` ```rust fn xrevrange<'a, K: ToRedisArgs + Send + Sync + 'a, E: ToRedisArgs + Send + Sync + 'a, S: ToRedisArgs + Send + Sync + 'a>( &'a mut self, key: K, end: E, start: S,) -> RedisResult { ... } ``` ```rust fn xrevrange_all<'a, K: ToRedisArgs + Send + Sync + 'a>( &'a mut self, key: K,) -> RedisResult { ... } ``` ```rust fn xrevrange_count<'a, K: ToRedisArgs + Send + Sync + 'a, E: ToRedisArgs + Send + Sync + 'a, S: ToRedisArgs + Send + Sync + 'a, C: ToRedisArgs + Send + Sync + 'a>( &'a mut self, key: K, end: E, start: S, count: C,) -> RedisResult { ... } ``` -------------------------------- ### Hotkeys START Command Source: https://docs.rs/redis/latest/src/redis/commands/hotkeys.rs.html Starts tracking hotkeys based on specified metrics and duration. At least one of CPU or network tracking must be enabled. The `COUNT` parameter specifies the number of top hotkeys to track, and `DURATION` sets the tracking period. ```APIDOC ## HOTKEYS START ### Description Starts tracking hotkeys based on CPU and/or network usage. The command can be configured with options to specify the number of top hotkeys to track (COUNT), the duration of tracking (DURATION), and the sampling ratio. ### Method ``` con.hotkeys_start(opts: HotkeysOptions) ``` ### Parameters #### Options (`HotkeysOptions`) - **cpu** (bool) - Enables tracking hotkeys by CPU time percentage. - **net** (bool) - Enables tracking hotkeys by network bytes percentage. - **count_k** (Option) - The number of top hotkeys to track (COUNT parameter). Must be between 1 and 64. - **duration_secs** (Option) - The duration in seconds for tracking (DURATION parameter). - **sample_ratio** (Option) - The sampling ratio for probabilistic tracking (SAMPLE parameter). - **slots** (Option>) - Specific slots to track in cluster mode (SLOTS parameter). ### Request Example ```rust use redis::{HotkeysOptions, HotkeysCommands}; let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_connection()?; // Track hotkeys by both CPU and network usage for 60 seconds, reporting top 10 let opts = HotkeysOptions::new_with_cpu() .and_net() .with_count(10)? .with_duration_secs(60); con.hotkeys_start(opts)?; ``` ### Response #### Success Response Returns `Ok(())` on successful execution. #### Error Response Returns a `redis::RedisError` if the command fails or options are invalid. ``` -------------------------------- ### Basic Redis Pipeline Example Source: https://docs.rs/redis/latest/redis/struct.Pipeline.html Demonstrates how to chain multiple commands like SET and MGET in a single pipeline. Use 'ignore()' to skip return values for commands like SET. ```rust let ((k1, k2),) : ((i32, i32),) = redis::pipe() .cmd("SET").arg("key_1").arg(42).ignore() .cmd("SET").arg("key_2").arg(43).ignore() .cmd("MGET").arg(&["key_1", "key_2"]).query(&mut con).unwrap(); ``` -------------------------------- ### Route HOTKEYS commands to a single node in Redis Cluster Source: https://docs.rs/redis/latest/src/redis/commands/hotkeys.rs.html Demonstrates how to route HOTKEYS START, GET, and STOP commands to a specific node within a Redis cluster using `route_command` and `SingleNodeRoutingInfo`. This is useful for inspecting individual shards. ```rust # #[cfg(feature = "cluster")] # { use redis::cluster::ClusterClient; use redis::cluster_routing::{RoutingInfo, SingleNodeRoutingInfo}; use redis::{cmd, FromRedisValue, HotkeysOptions, HotkeysResponse}; let nodes = vec!["redis://127.0.0.1:6379/", "redis://127.0.0.1:6378/"]; let client = ClusterClient::new(nodes).unwrap(); let mut connection = client.get_connection().unwrap(); // Route to a specific node let routing = RoutingInfo::SingleNode(SingleNodeRoutingInfo::ByAddress { host: "127.0.0.1".to_string(), port: 6379, }); // Start tracking on that specific node - track keys by CPU time percentage let opts = HotkeysOptions::new_with_cpu(); let _ = connection.route_command( &cmd("HOTKEYS").arg("START").arg(opts), routing.clone() ).unwrap(); // ... perform operations ... // Get metrics from the same node let value = connection.route_command( &cmd("HOTKEYS").arg("GET"), routing.clone() ).unwrap(); let response = HotkeysResponse::from_redis_value(value).unwrap(); // Stop tracking on that node let _ = connection.route_command( &cmd("HOTKEYS").arg("STOP"), routing ).unwrap(); # } ``` -------------------------------- ### Get Del Source: https://docs.rs/redis/latest/redis/struct.Connection.html Get the value of a key and delete it. ```APIDOC ## get_del ### Description Get the value of a key and delete it. ### Method `get_del` ### Parameters #### Path Parameters - **key** (K: ToSingleRedisArg + Send + Sync + 'a) - Required - The key whose value to get and delete. ### Response #### Success Response - **Option** - The value of the key, or None if the key does not exist. ```