discordBot/ISSUES.md
deadzilla bf166735a6 fix: исправить блокировку event loop и добавить retry задержку
- Добавить экспоненциальную задержку между попытками retry (1с, 2с, 4с) в pogoda.py
- Заменить time.sleep на await asyncio.sleep для неблокирующих ожиданий
- Обернуть requests.get в asyncio.to_thread для предотвращения блокировки event loop (news.py, cat.py, pogoda.py)
- Добавить правило AGENTS.md: не использовать эмодзи
- Добавить ISSUES.md с фиксацией проблем проекта
2026-05-26 10:24:26 +05:00

79 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Issues — список проблем проекта
> Состояние на: 2026-05-26
---
## 🔴 Критические
### 1. Retry без задержки между попытками ✅ РЕШЕНО
- **Где:** `commands/pogoda.py`, `console_commands/pogoda.py`
- **Проблема:** Цикл `for attempt in range(3)` не содержит `time.sleep()`. Все 3 попытки выполняются мгновенно, что бессмысленно при временных сетевых сбоях.
- **AGENTS.md обещает:** "Retry: 3 попытки с экспоненциальной задержкой" — но задержки нет.
- **Решение:** Добавить `time.sleep(2 ** attempt)` внутри цикла retry.
- **Статус:** Исправлено. Добавлена экспоненциальная задержка: 2 сек, 4 сек между попытками.
### 2. Блокировка event loop в async-методе ✅ РЕШЕНО
- **Где:** `commands/news.py`, `commands/cat.py`, `commands/pogoda.py`
- **Проблема:** Асинхронные методы вызывали синхронный `requests.get()`, блокируя весь event loop.
- **Решение:** Обернуть `requests.get()` в `await asyncio.to_thread()` и заменить `time.sleep()` на `await asyncio.sleep()`.
- **Статус:** Исправлено. В `news.py`, `cat.py`, `pogoda.py` все HTTP-запросы выполняются в отдельных потоках, а ожидания — неблокирующие.
---
## 🟡 Средние
### 3. Дублирование кода между Discord и console командами
- **Где:** `console_commands/pogoda.py` и `console_commands/news.py`
- **Проблема:** Логика погоды и новостей полностью продублирована. Изменения нужно вносить в два места.
- **Решение:** Вынести общую логику в `utils/` (например, `utils/weather.py`, `utils/rss.py`) и использовать её из обоих мест.
### 4. `from datetime import datetime` внутри метода
- **Где:** `commands/news.py``_format_and_send()`, строки 56 и 72
- **Проблема:** Импорт внутри метода — антипаттерн. Замедляет выполнение, нарушает PEP 8.
- **Решение:** Перенести `from datetime import datetime` в начало файла.
### 5. Консольная команда `cat` — заглушка
- **Где:** `console_commands/cat.py`
- **Проблема:** Функция просто печатает `"🐱 тут должен быть котик"`. Заглушка видна пользователю.
- **Решение:** Либо реализовать (вызвать API котиков), либо убрать из `ALL_CONSOLE_COMMANDS` и `README.md`.
### 6. `on_command_error` не сообщает пользователю об ошибке
- **Где:** `bot.py``on_command_error()`
- **Проблема:** Ошибки команд просто печатаются в `stdout`. Пользователь в чате не видит, что команда выполнилась с ошибкой.
- **Решение:** Добавить `await ctx.send("Произошла ошибка при выполнении команды.")` или отправить embed с деталями (если `ctx` не None).
### 7. Нет `.gitignore`
- **Где:** проект (файл отсутствует)
- **Проблема:** Нет явного `.gitignore`. `.env` может случайно попасть в репозиторий, хотя AGENTS.md говорит "`.env` в `.gitignore`".
- **Решение:** Создать `.gitignore` с правилами для Python (`__pycache__/`, `*.pyc`, `.env`, `venv/`, `*.egg-info/`).
### 8. `requests` без Session — нет переиспользования соединений
- **Где:** все файлы (`pogoda.py`, `news.py`)
- **Проблема:** Каждый `requests.get()` создаёт новое TCP-соединение. Для частых запросов это расточительно.
- **Решение:** Создать `requests.Session()` и использовать `session.get()`.
---
## 🟢 Малые улучшения
### 9. Linear search в `_translate_weather`
- **Где:** `commands/pogoda.py`, `console_commands/pogoda.py`
- **Проблема:** Метод `_translate_weather()` перебирает весь словарь `mapping` циклом `for key, value in mapping.items()`. При большом словаре — неэффективно.
- **Решение:** Сортировать ключи по длине (убывание) и использовать `re` или `any(key.lower() in text.lower() for key in sorted_keys)`.
### 10. Нет `__all__` в `__init__.py`
- **Где:** `commands/__init__.py`, `console_commands/__init__.py`
- **Проблема:** Нет явного экспорта публичного API модулей.
- **Решение:** Добавить `__all__ = ["ALL_COMMANDS"]` / `__all__ = ["ALL_CONSOLE_COMMANDS"]`.
### 11. Жёстко заданные URL в разных файлах
- **Где:** `commands/news.py` и `console_commands/news.py`
- **Проблема:** Константы `RSS_URL_ARTICLES` и `RSS_URL_POSTS` продублированы.
- **Решение:** Вынести в `config.py` и импортировать оттуда.
### 12. Потенциальная гонка при остановке бота
- **Где:** `bot.py`
- **Проблема:** `stop_event.set()` и `bot.close()` вызываются из `console_input()`, `KeyboardInterrupt` и `console_commands/stop.py`. Возможна гонка.
- **Решение:** Добавить флаг `is_stopping` или использовать `asyncio.Lock`.