62 lines
2.3 KiB
Python
62 lines
2.3 KiB
Python
# bot/management/commands/runbots.py
|
||
import asyncio
|
||
import logging
|
||
import signal
|
||
from typing import Sequence, Tuple
|
||
|
||
from django.core.management.base import BaseCommand
|
||
from bot.models import TelegramBot, BotConfig
|
||
from bot.bot_factory import get_all_active_bots_with_configs, build_application_for_bot
|
||
|
||
log = logging.getLogger(__name__)
|
||
|
||
class Command(BaseCommand):
|
||
help = "Запуск ВСЕХ активных ботов (PTB 22.3) в одном процессе."
|
||
|
||
def handle(self, *args, **options):
|
||
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s")
|
||
|
||
# ВАЖНО: ORM здесь, в синхронном контексте
|
||
bot_cfg_pairs: Sequence[Tuple[TelegramBot, BotConfig]] = get_all_active_bots_with_configs()
|
||
if not bot_cfg_pairs:
|
||
self.stderr.write(self.style.ERROR("Нет активных ботов (is_active=True)."))
|
||
return
|
||
|
||
asyncio.run(self._amain(bot_cfg_pairs))
|
||
|
||
async def _amain(self, bot_cfg_pairs: Sequence[Tuple[TelegramBot, BotConfig]]):
|
||
apps = []
|
||
try:
|
||
# Ни одной ORM-операции тут — только PTB
|
||
for tb, cfg in bot_cfg_pairs:
|
||
app, allowed_updates = build_application_for_bot(tb, cfg)
|
||
await app.initialize()
|
||
await app.start()
|
||
await app.updater.start_polling(allowed_updates=allowed_updates)
|
||
apps.append(app)
|
||
log.info("Bot started: %s (@%s)", tb.name, tb.username or "—")
|
||
|
||
# Ждём SIGINT/SIGTERM
|
||
stop_event = asyncio.Event()
|
||
|
||
def _stop(*_):
|
||
stop_event.set()
|
||
|
||
loop = asyncio.get_running_loop()
|
||
for sig in (signal.SIGINT, signal.SIGTERM):
|
||
try:
|
||
loop.add_signal_handler(sig, _stop)
|
||
except NotImplementedError:
|
||
pass # Windows
|
||
|
||
await stop_event.wait()
|
||
|
||
finally:
|
||
for app in reversed(apps):
|
||
try:
|
||
await app.updater.stop()
|
||
await app.stop()
|
||
await app.shutdown()
|
||
except Exception:
|
||
log.exception("Shutdown error")
|
||
log.info("All bots stopped gracefully.") |