dorm_alarm/bot.py
2025-09-26 00:22:38 +03:00

85 lines
No EOL
3.4 KiB
Python
Raw Permalink 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.

import asyncio
import logging
import signal
import sys
from init import bot, dp
from handlers import router, initialize_existing_users
# Конфигурация системы логирования для production среды
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(sys.stdout),
logging.FileHandler('bot.log', encoding='utf-8')
]
)
logger = logging.getLogger(__name__)
async def graceful_shutdown():
"""Корректное завершение работы с очисткой ресурсов"""
logger.info("Initiating graceful shutdown...")
# Остановка всех активных задач уведомлений
from handlers import notification_tasks
for user_id, task in notification_tasks.items():
task.cancel()
logger.info(f"Cancelled notification task for user {user_id}")
# Очистка webhook'ов и закрытие соединений
await bot.delete_webhook(drop_pending_updates=True)
await bot.session.close()
logger.info("Graceful shutdown completed")
async def main() -> None:
"""Главная точка входа приложения с полной инициализацией системы"""
try:
logger.info("Starting notification monitoring bot...")
# Регистрация обработчиков сигналов для graceful shutdown
def signal_handler():
logger.info("Received shutdown signal")
# Создание task для корректного завершения в event loop
asyncio.create_task(graceful_shutdown())
# Подключение обработчиков команд и callback'ов
dp.include_router(router)
# Очистка устаревших webhook'ов
await bot.delete_webhook(drop_pending_updates=True)
# Инициализация уведомлений для существующих пользователей
await initialize_existing_users()
logger.info("Bot initialization completed successfully")
logger.info("Starting polling mode...")
# Запуск long polling с оптимизированными параметрами
await dp.start_polling(
bot,
allowed_updates=dp.resolve_used_update_types(),
timeout=20, # Оптимизированный timeout для стабильности
relax=0.1 # Минимальная пауза между запросами
)
except Exception as e:
logger.critical(f"Critical error during bot startup: {e}")
sys.exit(1)
if __name__ == "__main__":
try:
# Установка политики event loop для Windows compatibility
if sys.platform.startswith('win'):
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
# Запуск основного процесса
asyncio.run(main())
except KeyboardInterrupt:
logger.info("Bot stopped by user (KeyboardInterrupt)")
except Exception as e:
logger.critical(f"Unhandled exception: {e}")
sys.exit(1)