This commit is contained in:
@@ -29,6 +29,12 @@
|
|||||||
- Прямой `git push dokku` вместо использования стороннего action
|
- Прямой `git push dokku` вместо использования стороннего action
|
||||||
- Более надежный и контролируемый процесс деплоя
|
- Более надежный и контролируемый процесс деплоя
|
||||||
|
|
||||||
|
### 🔍 Улучшено
|
||||||
|
- **Прекеш топиков**: Добавлен вывод списка топиков с 0 фолловерами
|
||||||
|
- После прекеша выводится список всех топиков без фолловеров по слагам
|
||||||
|
- Убраны избыточные логи из `precache_topics_followers`
|
||||||
|
- Более чистое и информативное логирование процесса кеширования
|
||||||
|
|
||||||
## [0.9.13] - 2025-08-27
|
## [0.9.13] - 2025-08-27
|
||||||
|
|
||||||
### 🗑️ Удалено
|
### 🗑️ Удалено
|
||||||
|
|||||||
44
cache/precache.py
vendored
44
cache/precache.py
vendored
@@ -1,6 +1,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
import orjson
|
||||||
from sqlalchemy import and_, func, join, select
|
from sqlalchemy import and_, func, join, select
|
||||||
|
|
||||||
# Импорт Author, AuthorFollower отложен для избежания циклических импортов
|
# Импорт Author, AuthorFollower отложен для избежания циклических импортов
|
||||||
@@ -76,12 +77,9 @@ async def precache_topics_followers(topic_id: int, session) -> None:
|
|||||||
followers_payload = fast_json_dumps(list(topic_followers))
|
followers_payload = fast_json_dumps(list(topic_followers))
|
||||||
await redis.execute("SET", f"topic:followers:{topic_id}", followers_payload)
|
await redis.execute("SET", f"topic:followers:{topic_id}", followers_payload)
|
||||||
|
|
||||||
# Добавляем логирование для отладки
|
# Логируем только если количество фолловеров равно 0
|
||||||
logger.debug(f"Precached {len(topic_followers)} followers for topic #{topic_id}")
|
|
||||||
if len(topic_followers) == 0:
|
if len(topic_followers) == 0:
|
||||||
logger.warning(f"⚠️ Topic #{topic_id} has 0 followers - this might indicate a data issue")
|
logger.debug(f"Topic #{topic_id} has 0 followers")
|
||||||
elif len(topic_followers) == 1:
|
|
||||||
logger.info(f"ℹ️ Topic #{topic_id} has exactly 1 follower - checking if this is correct")
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error precaching followers for topic #{topic_id}: {e}")
|
logger.error(f"Error precaching followers for topic #{topic_id}: {e}")
|
||||||
@@ -202,6 +200,42 @@ async def precache_data() -> None:
|
|||||||
# logger.debug(f"Finished precaching followers and authors for topic id={topic_dict.get('id')}")
|
# logger.debug(f"Finished precaching followers and authors for topic id={topic_dict.get('id')}")
|
||||||
logger.info(f"{len(topics)} topics and their followings precached")
|
logger.info(f"{len(topics)} topics and their followings precached")
|
||||||
|
|
||||||
|
# Выводим список топиков с 0 фолловерами
|
||||||
|
topics_with_zero_followers = []
|
||||||
|
for topic in topics:
|
||||||
|
topic_dict = topic.dict() if hasattr(topic, "dict") else topic
|
||||||
|
topic_id = topic_dict.get("id")
|
||||||
|
topic_slug = topic_dict.get("slug", "unknown")
|
||||||
|
|
||||||
|
# Пропускаем топики без ID
|
||||||
|
if not topic_id:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Получаем количество фолловеров из кеша
|
||||||
|
followers_cache_key = f"topic:followers:{topic_id}"
|
||||||
|
followers_data = await redis.execute("GET", followers_cache_key)
|
||||||
|
|
||||||
|
if followers_data:
|
||||||
|
followers_count = len(orjson.loads(followers_data))
|
||||||
|
if followers_count == 0:
|
||||||
|
topics_with_zero_followers.append(topic_slug)
|
||||||
|
else:
|
||||||
|
# Если кеш не найден, проверяем БД
|
||||||
|
with local_session() as check_session:
|
||||||
|
followers_count_result = check_session.execute(
|
||||||
|
select(func.count(TopicFollower.follower)).where(TopicFollower.topic == topic_id)
|
||||||
|
).scalar()
|
||||||
|
followers_count = followers_count_result or 0
|
||||||
|
if followers_count == 0:
|
||||||
|
topics_with_zero_followers.append(topic_slug)
|
||||||
|
|
||||||
|
if topics_with_zero_followers:
|
||||||
|
logger.info(f"📋 Топики с 0 фолловерами ({len(topics_with_zero_followers)}):")
|
||||||
|
for slug in sorted(topics_with_zero_followers):
|
||||||
|
logger.info(f" • {slug}")
|
||||||
|
else:
|
||||||
|
logger.info("✅ Все топики имеют фолловеров")
|
||||||
|
|
||||||
# authors
|
# authors
|
||||||
authors = get_with_stat(select(Author))
|
authors = get_with_stat(select(Author))
|
||||||
# logger.info(f"{len(authors)} authors found in database")
|
# logger.info(f"{len(authors)} authors found in database")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "publy-panel",
|
"name": "publy-panel",
|
||||||
"version": "0.9.13",
|
"version": "0.9.14",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "Publy, a modern platform for collaborative text creation, offers a user-friendly interface for authors, editors, and readers, supporting real-time collaboration and structured feedback.",
|
"description": "Publy, a modern platform for collaborative text creation, offers a user-friendly interface for authors, editors, and readers, supporting real-time collaboration and structured feedback.",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "discours-core"
|
name = "discours-core"
|
||||||
version = "0.9.13"
|
version = "0.9.14"
|
||||||
description = "Core backend for Discours.io platform"
|
description = "Core backend for Discours.io platform"
|
||||||
authors = [
|
authors = [
|
||||||
{name = "Tony Rewin", email = "tonyrewin@yandex.ru"}
|
{name = "Tony Rewin", email = "tonyrewin@yandex.ru"}
|
||||||
|
|||||||
Reference in New Issue
Block a user