diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d5d57ad..6aa3a7f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +#### [0.4.20] - 2025-05-03 +- Исправлена ошибка в классе `CacheRevalidationManager`: добавлена инициализация атрибута `_redis` +- Улучшена обработка соединения с Redis в менеджере ревалидации кэша: + - Автоматическое восстановление соединения в случае его потери + - Проверка соединения перед выполнением операций с кэшем + - Дополнительное логирование для упрощения диагностики проблем + #### [0.4.19] - 2025-04-14 - dropped `Shout.description` and `Draft.description` to be UX-generated - use redis to init views counters after migrator diff --git a/cache/revalidator.py b/cache/revalidator.py index 7be5041c..ac0c1ba1 100644 --- a/cache/revalidator.py +++ b/cache/revalidator.py @@ -8,6 +8,7 @@ from cache.cache import ( invalidate_cache_by_prefix, ) from resolvers.stat import get_with_stat +from services.redis import redis from utils.logger import root_logger as logger CACHE_REVALIDATION_INTERVAL = 300 # 5 minutes @@ -21,9 +22,19 @@ class CacheRevalidationManager: self.lock = asyncio.Lock() self.running = True self.MAX_BATCH_SIZE = 10 # Максимальное количество элементов для поштучной обработки + self._redis = redis # Добавлена инициализация _redis для доступа к Redis-клиенту async def start(self): """Запуск фонового воркера для ревалидации кэша.""" + # Проверяем, что у нас есть соединение с Redis + if not self._redis._client: + logger.warning("Redis connection not established. Waiting for connection...") + try: + await self._redis.connect() + logger.info("Redis connection established for revalidation manager") + except Exception as e: + logger.error(f"Failed to connect to Redis: {e}") + self.task = asyncio.create_task(self.revalidate_cache()) async def revalidate_cache(self): @@ -39,6 +50,10 @@ class CacheRevalidationManager: async def process_revalidation(self): """Обновление кэша для всех сущностей, требующих ревалидации.""" + # Проверяем соединение с Redis + if not self._redis._client: + return # Выходим из метода, если не удалось подключиться + async with self.lock: # Ревалидация кэша авторов if self.items_to_revalidate["authors"]: diff --git a/docs/caching.md b/docs/caching.md index 7c025be2..0a179764 100644 --- a/docs/caching.md +++ b/docs/caching.md @@ -147,16 +147,32 @@ await invalidate_topics_cache(456) ```python class CacheRevalidationManager: - # ... - async def process_revalidation(self): + def __init__(self, interval=CACHE_REVALIDATION_INTERVAL): # ... + self._redis = redis # Прямая ссылка на сервис Redis + + async def start(self): + # Проверка и установка соединения с Redis + # ... + + async def process_revalidation(self): + # Обработка элементов для ревалидации + # ... + def mark_for_revalidation(self, entity_id, entity_type): + # Добавляет сущность в очередь на ревалидацию # ... ``` Менеджер ревалидации работает как асинхронный фоновый процесс, который периодически (по умолчанию каждые 5 минут) проверяет наличие сущностей для ревалидации. -Особенности реализации: +**Взаимодействие с Redis:** +- CacheRevalidationManager хранит прямую ссылку на сервис Redis через атрибут `_redis` +- При запуске проверяется наличие соединения с Redis и при необходимости устанавливается новое +- Включена автоматическая проверка соединения перед каждой операцией ревалидации +- Система самостоятельно восстанавливает соединение при его потере + +**Особенности реализации:** - Для авторов и тем используется поштучная ревалидация каждой записи - Для шаутов и реакций используется батчевая обработка, с порогом в 10 элементов - При достижении порога система переключается на инвалидацию коллекций вместо поштучной обработки