"""Фоновый asyncio-цикл сканирования stale heartbeat (в процессе sac-api).""" from __future__ import annotations import asyncio import logging from app.config import get_settings from app.database import SessionLocal from app.services.host_silence_scan import dispatch_host_silence_notifications, run_host_silence_scan logger = logging.getLogger("sac.host_silence_scan") async def host_silence_scan_loop(stop_event: asyncio.Event) -> None: settings = get_settings() interval_sec = max(60, int(settings.sac_host_silence_scan_interval_minutes) * 60) logger.info( "host_silence background scan enabled (interval=%s min, stale=%s min)", settings.sac_host_silence_scan_interval_minutes, settings.sac_heartbeat_stale_minutes, ) while not stop_event.is_set(): try: await asyncio.to_thread(_run_scan_once) except Exception: logger.exception("host_silence background scan error") try: await asyncio.wait_for(stop_event.wait(), timeout=interval_sec) except asyncio.TimeoutError: continue def _run_scan_once() -> None: db = SessionLocal() try: results = run_host_silence_scan(db) notified = dispatch_host_silence_notifications(db, results) db.commit() if results: logger.info( "host_silence background: stale=%s created=%s notified=%s", len(results), sum(1 for r in results if r.created), notified, ) except Exception: db.rollback() raise finally: db.close()