121 lines
3.9 KiB
Python
121 lines
3.9 KiB
Python
import asyncio
|
|
import os
|
|
|
|
from apscheduler.triggers.cron import CronTrigger
|
|
|
|
from core.periodic_manager import periodic_task_manager
|
|
from database import async_session_maker, cancel_expired_pending_payments
|
|
from hooks.hooks import register_hook
|
|
from logger import logger
|
|
|
|
|
|
_TASKS_REGISTERED = False
|
|
|
|
|
|
async def _backup_loop(_bot, _sessionmaker) -> None:
|
|
from config import BACKUP_TIME
|
|
from utils.backup import backup_database
|
|
|
|
if BACKUP_TIME <= 0:
|
|
await asyncio.Event().wait()
|
|
return
|
|
while True:
|
|
error = await backup_database()
|
|
if error:
|
|
logger.error("[Backup] Ошибка: {}", error)
|
|
await asyncio.sleep(BACKUP_TIME)
|
|
|
|
|
|
async def _server_checks_loop(_bot, sessionmaker) -> None:
|
|
from config import PING_TIME
|
|
from servers import check_servers
|
|
|
|
if PING_TIME <= 0:
|
|
await asyncio.Event().wait()
|
|
return
|
|
await check_servers(sessionmaker=sessionmaker)
|
|
|
|
|
|
async def _scheduled_audit_drain() -> None:
|
|
from audit import drain_audit_redis_to_db
|
|
|
|
try:
|
|
drained = await drain_audit_redis_to_db(async_session_maker)
|
|
logger.info("[AuditDrain] Ночной drain завершён, записано событий: {}", drained)
|
|
except Exception as error:
|
|
logger.error("[AuditDrain] Ошибка ночного drain: {}", error)
|
|
|
|
|
|
async def _scheduled_stats_report() -> None:
|
|
from handlers.admin.stats.stats_handler import send_daily_stats_report
|
|
|
|
async with async_session_maker() as session:
|
|
await send_daily_stats_report(session)
|
|
|
|
|
|
async def _sweep_stale_payments_job() -> None:
|
|
async with async_session_maker() as session:
|
|
await cancel_expired_pending_payments(session)
|
|
|
|
|
|
def _register_periodic_tasks() -> None:
|
|
global _TASKS_REGISTERED
|
|
if _TASKS_REGISTERED:
|
|
return
|
|
from handlers.admin.sender.scheduled_service import scheduled_broadcasts_loop
|
|
from handlers.notifications.general_notifications import periodic_notifications
|
|
|
|
periodic_task_manager.register_loop_task(
|
|
"notifications",
|
|
lambda bot, sessionmaker: periodic_notifications(bot, sessionmaker=sessionmaker),
|
|
)
|
|
periodic_task_manager.register_loop_task("scheduled_broadcasts", lambda bot, sessionmaker: scheduled_broadcasts_loop(bot))
|
|
periodic_task_manager.register_loop_task("backup", _backup_loop)
|
|
periodic_task_manager.register_loop_task("server_checks", _server_checks_loop)
|
|
periodic_task_manager.register_cron_task(
|
|
"audit_drain_midnight",
|
|
_scheduled_audit_drain,
|
|
CronTrigger(hour=0, minute=0, timezone="Europe/Moscow"),
|
|
)
|
|
periodic_task_manager.register_cron_task(
|
|
"daily_stats_report",
|
|
_scheduled_stats_report,
|
|
CronTrigger(hour=0, minute=1, timezone="Europe/Moscow"),
|
|
)
|
|
periodic_task_manager.register_cron_task(
|
|
"sweep_stale_payments",
|
|
_sweep_stale_payments_job,
|
|
CronTrigger(minute=0, timezone="Europe/Moscow"),
|
|
)
|
|
_TASKS_REGISTERED = True
|
|
|
|
|
|
def _should_start_manager() -> bool:
|
|
if os.environ.get("NOTIFICATION_WORKER", "").strip() == "1":
|
|
return True
|
|
if os.environ.get("NOTIFICATION_WORKER_SEPARATE", "").strip() == "1":
|
|
return False
|
|
return True
|
|
|
|
|
|
async def ensure_periodic_task_manager_started(bot, sessionmaker) -> None:
|
|
_register_periodic_tasks()
|
|
if not _should_start_manager():
|
|
logger.info("[PeriodicManager] Пропуск старта в текущем процессе")
|
|
return
|
|
await periodic_task_manager.start(bot, sessionmaker)
|
|
|
|
|
|
async def ensure_periodic_task_manager_stopped() -> None:
|
|
await periodic_task_manager.stop()
|
|
|
|
|
|
@register_hook("startup")
|
|
async def start_periodic_task_manager(bot, sessionmaker, **_kwargs):
|
|
await ensure_periodic_task_manager_started(bot, sessionmaker)
|
|
|
|
|
|
@register_hook("shutdown")
|
|
async def stop_periodic_task_manager(**_kwargs):
|
|
await ensure_periodic_task_manager_stopped()
|