48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
|
|
"""APScheduler wrapper that ticks every minute and lets the checker decide
|
||
|
|
which feeds are due (per-feed intervals are evaluated in check_all_feeds)."""
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import logging
|
||
|
|
|
||
|
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||
|
|
from apscheduler.triggers.interval import IntervalTrigger
|
||
|
|
|
||
|
|
from .checker import check_all_feeds
|
||
|
|
|
||
|
|
log = logging.getLogger("scheduler")
|
||
|
|
|
||
|
|
_scheduler: AsyncIOScheduler | None = None
|
||
|
|
_JOB_ID = "check-feeds"
|
||
|
|
# Fixed tick; per-feed/global intervals are honoured inside check_all_feeds.
|
||
|
|
_TICK_SECONDS = 60
|
||
|
|
|
||
|
|
|
||
|
|
def start(interval_minutes: int) -> None:
|
||
|
|
global _scheduler
|
||
|
|
if _scheduler is not None:
|
||
|
|
return
|
||
|
|
_scheduler = AsyncIOScheduler(timezone="UTC")
|
||
|
|
_scheduler.add_job(
|
||
|
|
check_all_feeds,
|
||
|
|
trigger=IntervalTrigger(seconds=_TICK_SECONDS),
|
||
|
|
id=_JOB_ID,
|
||
|
|
max_instances=1,
|
||
|
|
coalesce=True,
|
||
|
|
replace_existing=True,
|
||
|
|
)
|
||
|
|
_scheduler.start()
|
||
|
|
log.info("Планировщик запущен (тик 60с), интервал по умолчанию %d мин", interval_minutes)
|
||
|
|
|
||
|
|
|
||
|
|
def reschedule(interval_minutes: int) -> None:
|
||
|
|
# The global interval is read live by the checker each tick, so there is
|
||
|
|
# nothing to reschedule — kept for API compatibility.
|
||
|
|
log.info("Интервал по умолчанию изменён на %d мин", interval_minutes)
|
||
|
|
|
||
|
|
|
||
|
|
def shutdown() -> None:
|
||
|
|
global _scheduler
|
||
|
|
if _scheduler is not None:
|
||
|
|
_scheduler.shutdown(wait=False)
|
||
|
|
_scheduler = None
|