sal/src/redisclient/README.md
Mahmoud Emad f002445c9e
Some checks failed
Rhai Tests / Run Rhai Tests (push) Waiting to run
Rhai Tests / Run Rhai Tests (pull_request) Has been cancelled
feat: Add PostgreSQL and Redis client support
- Add PostgreSQL client functionality for database interactions.
- Add Redis client functionality for cache and data store operations.
- Extend Rhai scripting with PostgreSQL and Redis client modules.
- Add documentation and test cases for both clients.
2025-05-09 09:45:50 +03:00

4.3 KiB

Redis Client Module

A robust Redis client wrapper for Rust applications that provides connection management, automatic reconnection, and a simple interface for executing Redis commands.

Features

  • Singleton Pattern: Maintains a global Redis client instance, so we don't re-int all the time.
  • Connection Management: Automatically handles connection creation and reconnection
  • Flexible Connectivity:
    • Tries Unix socket connection first ($HOME/hero/var/myredis.sock)
    • Falls back to TCP connection (localhost) if socket connection fails
  • Database Selection: Uses the REDISDB environment variable to select the Redis database (defaults to 0)
  • Authentication Support: Supports username/password authentication
  • Builder Pattern: Flexible configuration with a builder pattern
  • TLS Support: Optional TLS encryption for secure connections
  • Error Handling: Comprehensive error handling with detailed error messages
  • Thread Safety: Safe to use in multi-threaded applications

Usage

Basic Usage

use crate::redisclient::execute;
use redis::cmd;

// Execute a simple SET command
let mut set_cmd = redis::cmd("SET");
set_cmd.arg("my_key").arg("my_value");
let result: redis::RedisResult<()> = execute(&mut set_cmd);

// Execute a GET command
let mut get_cmd = redis::cmd("GET");
get_cmd.arg("my_key");
let value: redis::RedisResult<String> = execute(&mut get_cmd);
if let Ok(val) = value {
    println!("Value: {}", val);
}

Advanced Usage

use crate::redisclient::{get_redis_client, reset};

// Get the Redis client directly
let client = get_redis_client()?;

// Execute a command using the client
let mut cmd = redis::cmd("HSET");
cmd.arg("my_hash").arg("field1").arg("value1");
let result: redis::RedisResult<()> = client.execute(&mut cmd);

// Reset the Redis client connection
reset()?;

Builder Pattern

The module provides a builder pattern for flexible configuration:

use crate::redisclient::{RedisConfigBuilder, with_config};

// Create a configuration builder
let config = RedisConfigBuilder::new()
    .host("redis.example.com")
    .port(6379)
    .db(1)
    .username("user")
    .password("secret")
    .use_tls(true)
    .connection_timeout(30);

// Connect with the configuration
let client = with_config(config)?;

Unix Socket Connection

You can explicitly configure a Unix socket connection:

use crate::redisclient::{RedisConfigBuilder, with_config};

// Create a configuration builder for Unix socket
let config = RedisConfigBuilder::new()
    .use_unix_socket(true)
    .socket_path("/path/to/redis.sock")
    .db(1);

// Connect with the configuration
let client = with_config(config)?;

Environment Variables

  • REDISDB: Specifies the Redis database number to use (default: 0)
  • REDIS_HOST: Specifies the Redis host (default: 127.0.0.1)
  • REDIS_PORT: Specifies the Redis port (default: 6379)
  • REDIS_USERNAME: Specifies the Redis username for authentication
  • REDIS_PASSWORD: Specifies the Redis password for authentication
  • HOME: Used to determine the path to the Redis Unix socket

Connection Strategy

  1. First attempts to connect via Unix socket at $HOME/hero/var/myredis.sock
  2. If socket connection fails, falls back to TCP connection at redis://127.0.0.1/
  3. If both connection methods fail, returns an error

Error Handling

The module provides detailed error messages that include:

  • The connection method that failed
  • The path to the socket that was attempted
  • The underlying Redis error

Testing

The module includes both unit tests and integration tests:

  • Unit tests that mock Redis functionality
  • Integration tests that require a real Redis server
  • Tests automatically skip if Redis is not available

Unit Tests

  • Tests for the builder pattern and configuration
  • Tests for connection URL building
  • Tests for environment variable handling

Integration Tests

  • Tests for basic Redis operations (SET, GET, EXPIRE)
  • Tests for hash operations (HSET, HGET, HGETALL, HDEL)
  • Tests for list operations (RPUSH, LLEN, LRANGE, LPOP)
  • Tests for error handling (invalid commands, wrong data types)

Run the tests with:

cargo test --lib redisclient::tests

Thread Safety

The Redis client is wrapped in an Arc<Mutex<>> to ensure thread safety when accessing the global instance.