# redis-rs Library Patterns - Key Excerpts for Cache Client **Authority Tier:** Tier 3 (Community) **Source:** https://docs.rs/redis/ + https://github.com/redis-rs/redis-rs **Relevance:** Canonical Rust implementation patterns for Redis clients, widely adopted in ecosystem --- ## Connection Management > **User fills in:** Review redis-rs documentation on connection handling > > Look for: > - `redis::Client::open()` - One-time vs pooled > - Connection pooling with r2d2 or bb8 > - Async vs sync API usage **Key Claims:** - `cache/connection_pooling :: library = "r2d2"` - **Consequence:** Creating new `Client::open()` per request exhausts file descriptors - `cache/async_api :: required = true` - **Consequence:** Using blocking API in async context blocks event loop - throughput collapse **Example (from redis-rs docs):** ```rust // ❌ VIOLATION: New connection per request let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_connection()?; // Blocking! // ✅ COMPLIANT: Connection pool let manager = RedisConnectionManager::new("redis://127.0.0.1/")?; let pool = r2d2::Pool::builder().build(manager)?; let mut con = pool.get()?; ``` --- ## Async Patterns > **User fills in:** Review redis-rs async examples > > Look for: > - `redis::aio::Connection` usage > - Tokio integration > - Error handling in async contexts **Key Claims:** - `cache/async_runtime :: required = "tokio"` - **Consequence:** Mixing async runtimes (tokio + async-std) causes runtime panics - `cache/async_methods :: required = true` - **Consequence:** Calling `.blocking_get()` in async code blocks executor threads **Example (from redis-rs GitHub):** ```rust // ✅ COMPLIANT: Async API let client = redis::Client::open("redis://127.0.0.1/")?; let mut con = client.get_async_connection().await?; let value: Option = con.get("key").await?; ``` --- ## Error Handling > **User fills in:** Review redis-rs error types and handling patterns > > Look for: > - `redis::RedisError` variants > - Connection failures vs command failures > - Retry strategies **Key Claims:** - `cache/error_handling :: pattern = "Result"` - **Consequence:** Unwrapping Redis results causes panics on network failures - `cache/retry_on_error :: types = ["ConnectionRefused", "IoError"]` - **Consequence:** Not retrying transient errors causes unnecessary failures **Example (from redis-rs issues):** ```rust // ❌ VIOLATION: Unwrap causes panic on network failure let value: String = con.get("key").unwrap(); // ✅ COMPLIANT: Proper error handling match con.get("key") { Ok(value) => Some(value), Err(e) if is_transient(&e) => retry(), Err(e) => return Err(e.into()), } ``` --- ## Common Patterns (from GitHub Issues) > **User fills in:** Search redis-rs GitHub issues for common problems > > Keywords to search: > - "connection pool" > - "timeout" > - "memory leak" > - "panic" **Key Claims (extracted from issues):** - `cache/ttl_default :: recommended = 3600` # 1 hour - **Consequence:** From issue #234 - "Forgot to set TTL, cache grew to 10 GB" - Provenance: https://github.com/redis-rs/redis-rs/issues/234 - `cache/pipeline_usage :: recommended = true` - **Consequence:** From issue #156 - "Sequential SET commands 10x slower than pipeline" - Provenance: https://github.com/redis-rs/redis-rs/issues/156 - `cache/connection_timeout :: maximum = 30` - **Consequence:** From issue #89 - "60s timeout caused request queuing during Redis restart" - Provenance: https://github.com/redis-rs/redis-rs/issues/89 --- ## Configuration Patterns > **User fills in:** Review redis-rs examples/ directory > > Look for: > - Config struct patterns > - Builder pattern usage > - Default value recommendations **Key Claims:** - `cache/config/builder_pattern :: required = true` - **Consequence:** Manual struct construction error-prone (missing required fields) - `cache/config/validation :: required = true` - **Consequence:** Invalid config (e.g., timeout=0) accepted at compile time, fails at runtime **Example (from redis-rs examples):** ```rust #[derive(Clone)] pub struct CacheConfig { pub url: String, pub max_connections: usize, // ✅ Required, not Option pub timeout: Duration, // ✅ Required, validated > 0 pub ttl: Duration, // ✅ Required for expiration } impl CacheConfig { pub fn validate(&self) -> Result<(), ConfigError> { if self.timeout.is_zero() { return Err(ConfigError::InvalidTimeout); } // ... } } ``` --- ## Extraction Guide 1. **Browse redis-rs documentation:** ```bash open https://docs.rs/redis/latest/redis/ ``` 2. **Review example code:** ```bash git clone https://github.com/redis-rs/redis-rs cd redis-rs/examples/ # Read: basic.rs, async.rs, connection-pool.rs ``` 3. **Search GitHub issues for patterns:** ```bash # On GitHub: redis-rs/redis-rs # Search: "memory leak", "timeout", "panic", "connection pool" # Read issue descriptions and resolutions ``` 4. **Extract usage patterns:** - Connection management (pooling vs one-shot) - Async vs sync API usage - Error handling strategies - Configuration validation 5. **Map to concept paths:** - `cache/connection_pooling` - `cache/async_api` - `cache/error_handling` - `cache/config/validation` 6. **Add to claims with provenance:** - Provenance: "redis-rs v0.24.0 documentation - Connection Pooling" - Or: "redis-rs GitHub issue #234 - Memory leak from missing TTL" - Link to docs page or issue URL