← Назад к документации
feed
Исходный код Rust - Trading AI
📄 Rust
📦 Модуль
🔧 Исходный код
// ===========================
// File: src/feed.rs (NEW)
// ===========================

use crate::types::Tick;
use crate::redis::{RedisCore, get_redis_conn};
use redis::AsyncCommands;
use std::sync::Arc;

/// Модуль для чтения/публикации тиков через Redis.
pub struct Feed {
    redis: Arc<RedisCore>,
}

impl Feed {
    pub fn new(redis: Arc<RedisCore>) -> Self {
        Feed { redis }
    }

    /// Получаем последний тик по символу из Redis.
    ///
    /// Монитор пишет:
    ///   - список: LPUSH hb:ticks:{SYMBOL} "<json Tick>"
    ///   - последний тик: SET   hb:last:{SYMBOL} "<json Tick>"
    ///
    /// Здесь используем именно hb:last:{SYMBOL}, чтобы:
    ///   - не дёргать лишний раз список
    ///   - всегда брать актуальный последний тик O(1)
    pub async fn get_tick_from_redis(&self, symbol: &str) -> Option<Tick> {
        let mut conn = match get_redis_conn(&self.redis).await {
            Ok(c) => c,
            Err(_) => return None,
        };

        let key = format!("hb:last:{}", symbol);

        let raw: Option<String> = conn.get(&key).await.ok()?;
        raw.and_then(|s| serde_json::from_str::<Tick>(&s).ok())
    }

    /// Публикуем тик в Redis — вспомогательный метод,
    /// если захочешь где-то ещё генерировать тики.
    ///
    /// Здесь пишем ТОЛЬКО в hb:ticks:{SYMBOL}, как "историю",
    /// last по-хорошему должен писать монитор или отдельный парсер.
    pub async fn publish_tick_to_redis(&self, tick: &Tick) {
        if let Ok(mut conn) = get_redis_conn(&self.redis).await {
            let key_list = format!("hb:ticks:{}", tick.symbol);
            if let Ok(value) = serde_json::to_string(tick) {
                let _: redis::RedisResult<i64> = conn.lpush(&key_list, &value).await;
                // ограничиваем хвост до 1000 элементов
                let _: redis::RedisResult<i64> = conn.ltrim(&key_list, 0, 999).await;
            }
        }
    }
}