import asyncio from apscheduler.schedulers.asyncio import AsyncIOScheduler _scheduler: AsyncIOScheduler | None = None SETTINGS_DEFAULTS = { "sync_interval_seconds": "900", "log_retention_days": "90", "sync_cycle_timeout_seconds": "1800", "task_poll_timeout_seconds": "600", "replica_suspend_threshold": "5", "max_concurrent_requests": "4", "alert_target_type": "", "alert_target_url": "", "alert_target_token": "", "alert_error_threshold": "5", "alert_cooldown_seconds": "3600", } def get_setting(settings: dict, key: str) -> str: return settings.get(key) or SETTINGS_DEFAULTS.get(key, "") def get_setting_int(settings: dict, key: str) -> int: return int(get_setting(settings, key) or SETTINGS_DEFAULTS[key]) async def _sync_job() -> None: from .sync.engine import run_sync_cycle await run_sync_cycle(triggered_by="scheduler") def start_scheduler(interval_seconds: int = 900) -> AsyncIOScheduler: global _scheduler _scheduler = AsyncIOScheduler() _scheduler.add_job( _sync_job, "interval", seconds=interval_seconds, id="sync_job", replace_existing=True, max_instances=1, ) _scheduler.start() return _scheduler def reschedule(interval_seconds: int) -> None: if _scheduler is None: return _scheduler.reschedule_job( "sync_job", trigger="interval", seconds=interval_seconds, ) def stop_scheduler() -> None: if _scheduler: _scheduler.shutdown(wait=False)