This commit is contained in:
parent
56db33d7f1
commit
dce05342df
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -159,4 +159,5 @@ dokku_config
|
||||||
views.json
|
views.json
|
||||||
*.pem
|
*.pem
|
||||||
*.key
|
*.key
|
||||||
*.crt
|
*.crt
|
||||||
|
*cache.json
|
|
@ -1,4 +1,4 @@
|
||||||
#### [0.4.8]
|
#### [0.4.8] - 2025-02-03
|
||||||
- `Reaction.deleted_at` filter on `update_reaction` resolver added
|
- `Reaction.deleted_at` filter on `update_reaction` resolver added
|
||||||
- `triggers` module updated with `after_shout_handler`, `after_reaction_handler` for cache revalidation
|
- `triggers` module updated with `after_shout_handler`, `after_reaction_handler` for cache revalidation
|
||||||
- `after_shout_handler`, `after_reaction_handler` now also handle `deleted_at` field
|
- `after_shout_handler`, `after_reaction_handler` now also handle `deleted_at` field
|
||||||
|
|
86
cache/cache.py
vendored
86
cache/cache.py
vendored
|
@ -156,43 +156,37 @@ async def get_cached_authors_by_ids(author_ids: List[int]) -> List[dict]:
|
||||||
async def get_cached_topic_followers(topic_id: int):
|
async def get_cached_topic_followers(topic_id: int):
|
||||||
"""
|
"""
|
||||||
Получает подписчиков темы по ID, используя кеш Redis.
|
Получает подписчиков темы по ID, используя кеш Redis.
|
||||||
Если данные отсутствуют в кеше, извлекает из базы данных и кеширует их.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
topic_id: Идентификатор темы, подписчиков которой необходимо получить.
|
topic_id: ID темы
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[dict]: Список подписчиков темы, каждый элемент представляет собой словарь с данными автора.
|
List[dict]: Список подписчиков с их данными
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Попытка получить данные из кеша
|
cache_key = CACHE_KEYS["TOPIC_FOLLOWERS"].format(topic_id)
|
||||||
cached = await redis_operation("GET", f"topic:followers:{topic_id}")
|
cached = await redis_operation("GET", cache_key)
|
||||||
|
|
||||||
if cached:
|
if cached:
|
||||||
followers_ids = json.loads(cached)
|
followers_ids = json.loads(cached)
|
||||||
logger.debug(f"Cached {len(followers_ids)} followers for topic #{topic_id}")
|
logger.debug(f"Found {len(followers_ids)} cached followers for topic #{topic_id}")
|
||||||
followers = await get_cached_authors_by_ids(followers_ids)
|
return await get_cached_authors_by_ids(followers_ids)
|
||||||
return followers
|
|
||||||
|
|
||||||
# Если данные не найдены в кеше, загрузка из базы данных
|
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
result = (
|
followers_ids = [
|
||||||
session.query(Author.id)
|
f[0] for f in session.query(Author.id)
|
||||||
.join(TopicFollower, TopicFollower.follower == Author.id)
|
.join(TopicFollower, TopicFollower.follower == Author.id)
|
||||||
.filter(TopicFollower.topic == topic_id)
|
.filter(TopicFollower.topic == topic_id)
|
||||||
.all()
|
.all()
|
||||||
)
|
]
|
||||||
followers_ids = [f[0] for f in result]
|
|
||||||
|
await redis_operation("SETEX", cache_key, value=json.dumps(followers_ids), ttl=CACHE_TTL)
|
||||||
# Кэширование результатов
|
|
||||||
await redis_operation("SET", f"topic:followers:{topic_id}", json.dumps(followers_ids))
|
|
||||||
|
|
||||||
# Получение подробной информации о подписчиках по их ID
|
|
||||||
followers = await get_cached_authors_by_ids(followers_ids)
|
followers = await get_cached_authors_by_ids(followers_ids)
|
||||||
logger.debug(f"Topic#{topic_id} followers fetched and cached: {len(followers)} followers found.")
|
logger.debug(f"Cached {len(followers)} followers for topic #{topic_id}")
|
||||||
return followers
|
return followers
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Ошибка при получении подписчиков для темы #{topic_id}: {str(e)}")
|
logger.error(f"Error getting followers for topic #{topic_id}: {str(e)}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
@ -410,34 +404,38 @@ async def cache_related_entities(shout: Shout):
|
||||||
|
|
||||||
async def invalidate_shout_related_cache(shout: Shout, author_id: int):
|
async def invalidate_shout_related_cache(shout: Shout, author_id: int):
|
||||||
"""
|
"""
|
||||||
Инвалидирует весь кэш, связанный с публикацией
|
Инвалидирует весь кэш, связанный с публикацией и её связями
|
||||||
|
|
||||||
|
Args:
|
||||||
|
shout: Объект публикации
|
||||||
|
author_id: ID автора
|
||||||
"""
|
"""
|
||||||
# Базовые ленты
|
cache_keys = {
|
||||||
cache_keys = [
|
|
||||||
"feed", # основная лента
|
"feed", # основная лента
|
||||||
f"author_{author_id}", # публикации автора
|
f"author_{author_id}", # публикации автора
|
||||||
"random_top", # случайные топовые
|
"random_top", # случайные топовые
|
||||||
"unrated", # неоцененные
|
"unrated", # неоцененные
|
||||||
"recent", # последние публикации
|
"recent", # последние
|
||||||
"coauthored", # совместные публикации
|
"coauthored", # совместные
|
||||||
f"authored_{author_id}", # авторские публикации
|
}
|
||||||
f"followed_{author_id}", # подписки автора
|
|
||||||
]
|
# Добавляем ключи авторов
|
||||||
|
cache_keys.update(
|
||||||
|
f"author_{a.id}" for a in shout.authors
|
||||||
|
)
|
||||||
|
cache_keys.update(
|
||||||
|
f"authored_{a.id}" for a in shout.authors
|
||||||
|
)
|
||||||
|
|
||||||
|
# Добавляем ключи тем
|
||||||
|
cache_keys.update(
|
||||||
|
f"topic_{t.id}" for t in shout.topics
|
||||||
|
)
|
||||||
|
cache_keys.update(
|
||||||
|
f"topic_shouts_{t.id}" for t in shout.topics
|
||||||
|
)
|
||||||
|
|
||||||
# Добавляем ключи для всех авторов публикации
|
await invalidate_shouts_cache(list(cache_keys))
|
||||||
for author in shout.authors:
|
|
||||||
cache_keys.extend(
|
|
||||||
[f"author_{author.id}", f"authored_{author.id}", f"followed_{author.id}", f"coauthored_{author.id}"]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Добавляем ключи для тем
|
|
||||||
for topic in shout.topics:
|
|
||||||
cache_keys.extend(
|
|
||||||
[f"topic_{topic.id}", f"topic_shouts_{topic.id}", f"topic_recent_{topic.id}", f"topic_top_{topic.id}"]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Инвалидируем все ключи
|
|
||||||
await invalidate_shouts_cache(cache_keys)
|
|
||||||
|
|
||||||
|
|
||||||
async def redis_operation(operation: str, key: str, value=None, ttl=None):
|
async def redis_operation(operation: str, key: str, value=None, ttl=None):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user