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)