← Назад к главному
# feed.rs - Модуль для чтения/публикации тиков через Redis ## 📋 Назначение модуля `Feed` - модуль для чтения/публикации тиков через Redis. **Основная логика:** 1. **Чтение тика** - получает последний тик из Redis (`hb:last:{SYMBOL}`) 2. **Публикация тика** - публикует тик в Redis (`hb:ticks:{SYMBOL}`) 3. **История тиков** - хранит последние 1000 тиков в списке **Используется в:** - В будущем для чтения тиков (в текущей версии не используется) --- ## 🏗️ Структура модуля ### Структура `Feed` **Строки:** 11-13 ```rust pub struct Feed { redis: Arc, } ``` **Поля:** | Поле | Тип | Описание | |------|-----|----------| | `redis` | `Arc` | Клиент Redis | --- ## 🔄 Основные функции ### Функция `Feed::new()` **Строки:** 16-18 **Сигнатура:** ```rust pub fn new(redis: Arc) -> Self ``` **Возвращает:** - `Feed` - новый экземпляр Feed **Алгоритм:** ```rust Feed { redis } ``` --- ### Функция `Feed::get_tick_from_redis()` **Строки:** 29-39 **Сигнатура:** ```rust pub async fn get_tick_from_redis(&self, symbol: &str) -> Option ``` **Параметры:** - `symbol` - символ контракта **Возвращает:** - `Some(Tick)` - последний тик - `None` - тик не найден или ошибка **Алгоритм:** --- #### Этап 1: Получение подключения к Redis **Строки:** 30-33 ```rust let mut conn = match get_redis_conn(&self.redis).await { Ok(c) => c, Err(_) => return None, }; ``` **Что делает:** - Пытается получить подключение - При ошибке → возвращает `None` --- #### Этап 2: Формирование ключа **Строка:** 35 ```rust let key = format!("hb:last:{}", symbol); ``` --- #### Этап 3: Получение тика из Redis **Строки:** 37-38 ```rust let raw: Option = conn.get(&key).await.ok()?; raw.and_then(|s| serde_json::from_str::(&s).ok()) ``` **Что делает:** - Получает строку из Redis по ключу `hb:last:{symbol}` - Парсит строку в `Tick` - Возвращает `Some(Tick)` или `None` при ошибке **Пример ключа:** ``` hb:last:MEMES_USDT ``` **Пример значения:** ```json { "symbol": "MEMES_USDT", "mid": 0.00200050, "chg_pct": 45.5, "ts": 1771747635, "bid": 0.001990, "ask": 0.002010, "bid_qty": 50000.0, "ask_qty": 48000.0 } ``` --- ### Функция `Feed::publish_tick_to_redis()` **Строки:** 46-55 **Сигнатура:** ```rust pub async fn publish_tick_to_redis(&self, tick: &Tick) ``` **Параметры:** - `tick` - тик для публикации **Возвращает:** - Ничего (возвращает при ошибке) **Алгоритм:** --- #### Этап 1: Получение подключения к Redis **Строки:** 47-48 ```rust if let Ok(mut conn) = get_redis_conn(&self.redis).await { ``` **Что делает:** - Пытается получить подключение - При ошибке → возвращает --- #### Этап 2: Формирование ключа **Строка:** 48 ```rust let key_list = format!("hb:ticks:{}", tick.symbol); ``` **Пример ключа:** ``` hb:ticks:MEMES_USDT ``` --- #### Этап 3: Сериализация тика **Строки:** 49 ```rust if let Ok(value) = serde_json::to_string(tick) { ``` --- #### Этап 4: Добавление тика в список **Строки:** 50-52 ```rust let _: redis::RedisResult = conn.lpush(&key_list, &value).await; // ограничиваем хвост до 1000 элементов let _: redis::RedisResult = conn.ltrim(&key_list, 0, 999).await; ``` **Что делает:** - `LPUSH` - добавляет тик в начало списка - `LTRIM 0 999` - ограничивает список до 1000 элементов --- ## 📊 Redis ключи | Ключ | Тип | Описание | |------|-----|----------| | `hb:last:{symbol}` | String | Последний тик (используется для чтения) | | `hb:ticks:{symbol}` | List | Список тиков (максимум 1000, используется как история) | --- ## ⚠️ Критические моменты ### 1. Используется именно hb:last: для чтения **Строки:** 26-28 ```rust /// Здесь используем именно hb:last:{SYMBOL}, чтобы: /// - не дергать лишний раз список /// - всегда брать актуальный последний тик O(1) ``` **Почему это важно:** - `hb:last:{symbol}` - O(1) операция - `hb:ticks:{symbol}` - список, доступ к последнему элементу O(N) - Всегда берём актуальный последний тик --- ### 2. Публикация только в hb:ticks: (история) **Строки:** 44-45 ```rust /// Здесь пишем ТОЛЬКО в hb:ticks:{SYMBOL}, как "историю", /// last по-хорошему должен писать монитор или отдельный парсер. ``` **Что это значит:** - `publish_tick_to_redis()` пишет только в `hb:ticks:{symbol}` - `hb:last:{symbol}` должен писать монитор (monitor.rs) --- ### 3. Ошибки игнорируются **Строки:** 32, 47 ```rust Err(_) => return None, ``` **Что это значит:** - При ошибке Redis → возвращаем `None` или игнорируем - Не паникуем, продолжаем работу --- ## 📚 Связанные файлы | Файл | Связь | |------|-------| | `src/types.rs` | Структура Tick | | `src/redis.rs` | Redis клиент | | `src/monitor.rs` | Пишет в hb:last: и hb:ticks: | --- ## 🎯 Резюме **Что делает feed.rs:** 1. ✅ Читает последний тик из Redis (`hb:last:{symbol}`) 2. ✅ Публикует тик в Redis (`hb:ticks:{symbol}`) 3. ✅ Хранит историю последних 1000 тиков **Feed методы:** - `new(redis)` - создание Feed - `get_tick_from_redis(symbol)` - получить последний тик - `publish_tick_to_redis(tick)` - опубликовать тик **Redis ключи:** - `hb:last:{symbol}` - последний тик (для чтения) - `hb:ticks:{symbol}` - список тиков (история, максимум 1000) **Критические моменты:** - 🔥 Для чтения используем `hb:last:` (O(1) операция) - 🔥 Для публикации пишем в `hb:ticks:` (история) - 🔥 Ошибки Redis игнорируются --- **Дата создания:** 2026-02-22 **Автор:** Claude Code Assistant **Версия:** 1.0