← Назад к документации
redis
Исходный код Rust - Trading AI
📄 Rust
📦 Модуль
🔧 Исходный код

use anyhow::{Context, Result};

/// RedisCore struct to manage Redis connections and commands.
pub struct RedisCore {
    pub client: redis::Client,
}

impl RedisCore {
    /// Initializes a new RedisCore instance.
    pub fn new(redis_url: &str) -> Result<Self> {
        let client = redis::Client::open(redis_url)
            .context("Failed to create Redis client")?;
        Ok(RedisCore { client })
    }

    /// Проверяет подключение к Redis командой PING
    pub async fn ping(&self) -> Result<()> {
        let mut conn = self.get_conn().await
            .context("❌ ОШИБКА: Redis сервер не запущен или недоступен!")?;

        let pong: String = redis::cmd("PING")
            .query_async(&mut conn)
            .await
            .context("❌ ОШИБКА: Redis не отвечает на PING!")?;

        if pong != "PONG" {
            anyhow::bail!("❌ ОШИБКА: Redis вернул неверный ответ: {}", pong);
        }

        Ok(())
    }

    /// Удаляет все ключи с заданным префиксом (например, "hb:*")
    pub async fn delete_by_prefix(&self, prefix: &str) -> Result<usize> {
        let mut conn = self.get_conn().await
            .context("❌ ОШИБКА: Не удалось подключиться к Redis для удаления!")?;

        // Используем SCAN для безопасного поиска ключей
        let mut keys: Vec<String> = Vec::new();
        let mut cursor: usize = 0;

        loop {
            let (next_cursor, batch): (usize, Vec<String>) = redis::cmd("SCAN")
                .arg(cursor)
                .arg("MATCH")
                .arg(prefix)
                .arg("COUNT")
                .arg(100)
                .query_async(&mut conn)
                .await
                .context("❌ ОШИБКА: Не удалось выполнить SCAN!")?;

            keys.extend(batch);

            cursor = next_cursor;
            if cursor == 0 {
                break;
            }
        }

        if !keys.is_empty() {
            let deleted: usize = redis::cmd("DEL")
                .arg(keys.as_slice())
                .query_async(&mut conn)
                .await
                .context("❌ ОШИБКА: Не удалось выполнить DEL!")?;

            Ok(deleted)
        } else {
            Ok(0)
        }
    }

    /// Asynchronously retrieves a Redis connection.
    pub async fn get_conn(&self) -> Result<redis::aio::MultiplexedConnection> {
        let conn = self.client.get_multiplexed_async_connection().await
            .context("Failed to get Redis connection")?;
        Ok(conn)
    }
}

/// Helper function to get a connection from RedisCore.
pub async fn get_redis_conn(redis: &RedisCore) -> Result<redis::aio::MultiplexedConnection> {
    redis.get_conn().await
}