2024-08-07 05:42:59 +00:00
|
|
|
|
import asyncio
|
2024-08-09 06:37:06 +00:00
|
|
|
|
|
2025-01-16 03:49:15 +00:00
|
|
|
|
from cache.cache import cache_author, cache_topic, get_cached_author, get_cached_topic
|
2024-11-02 08:56:47 +00:00
|
|
|
|
from resolvers.stat import get_with_stat
|
2024-08-07 05:57:56 +00:00
|
|
|
|
from utils.logger import root_logger as logger
|
2024-08-07 05:42:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CacheRevalidationManager:
|
2024-08-07 06:51:09 +00:00
|
|
|
|
def __init__(self, interval=60):
|
|
|
|
|
"""Инициализация менеджера с заданным интервалом проверки (в секундах)."""
|
|
|
|
|
self.interval = interval
|
|
|
|
|
self.items_to_revalidate = {"authors": set(), "topics": set(), "shouts": set(), "reactions": set()}
|
|
|
|
|
self.lock = asyncio.Lock()
|
|
|
|
|
self.running = True
|
2024-08-07 05:42:59 +00:00
|
|
|
|
|
2024-08-07 06:51:09 +00:00
|
|
|
|
async def start(self):
|
|
|
|
|
"""Запуск фонового воркера для ревалидации кэша."""
|
2024-11-01 21:26:57 +00:00
|
|
|
|
self.task = asyncio.create_task(self.revalidate_cache())
|
2024-08-07 05:42:59 +00:00
|
|
|
|
|
|
|
|
|
async def revalidate_cache(self):
|
2024-08-07 06:51:09 +00:00
|
|
|
|
"""Циклическая проверка и ревалидация кэша каждые self.interval секунд."""
|
|
|
|
|
try:
|
|
|
|
|
while self.running:
|
|
|
|
|
await asyncio.sleep(self.interval)
|
|
|
|
|
await self.process_revalidation()
|
|
|
|
|
except asyncio.CancelledError:
|
|
|
|
|
logger.info("Revalidation worker was stopped.")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"An error occurred in the revalidation worker: {e}")
|
2024-08-07 05:42:59 +00:00
|
|
|
|
|
|
|
|
|
async def process_revalidation(self):
|
2024-08-07 06:51:09 +00:00
|
|
|
|
"""Обновление кэша для всех сущностей, требующих ревалидации."""
|
|
|
|
|
async with self.lock:
|
|
|
|
|
# Ревалидация кэша авторов
|
|
|
|
|
for author_id in self.items_to_revalidate["authors"]:
|
2024-11-02 08:56:47 +00:00
|
|
|
|
author = await get_cached_author(author_id, get_with_stat)
|
2024-08-07 06:51:09 +00:00
|
|
|
|
if author:
|
|
|
|
|
await cache_author(author)
|
|
|
|
|
self.items_to_revalidate["authors"].clear()
|
|
|
|
|
|
|
|
|
|
# Ревалидация кэша тем
|
|
|
|
|
for topic_id in self.items_to_revalidate["topics"]:
|
|
|
|
|
topic = await get_cached_topic(topic_id)
|
|
|
|
|
if topic:
|
|
|
|
|
await cache_topic(topic)
|
|
|
|
|
self.items_to_revalidate["topics"].clear()
|
2024-08-07 05:42:59 +00:00
|
|
|
|
|
|
|
|
|
def mark_for_revalidation(self, entity_id, entity_type):
|
|
|
|
|
"""Отметить сущность для ревалидации."""
|
|
|
|
|
self.items_to_revalidate[entity_type].add(entity_id)
|
|
|
|
|
|
2024-11-01 21:26:57 +00:00
|
|
|
|
async def stop(self):
|
2024-08-07 06:51:09 +00:00
|
|
|
|
"""Остановка фонового воркера."""
|
|
|
|
|
self.running = False
|
2024-11-02 09:09:24 +00:00
|
|
|
|
if hasattr(self, "task"):
|
2024-11-01 21:26:57 +00:00
|
|
|
|
self.task.cancel()
|
|
|
|
|
try:
|
|
|
|
|
await self.task
|
|
|
|
|
except asyncio.CancelledError:
|
|
|
|
|
pass
|
2024-08-07 06:51:09 +00:00
|
|
|
|
|
2024-08-07 05:42:59 +00:00
|
|
|
|
|
2024-08-07 06:51:09 +00:00
|
|
|
|
revalidation_manager = CacheRevalidationManager(interval=300) # Ревалидация каждые 5 минут
|