You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
2.2 KiB
Python

"""
APScheduler-based batch scheduler for the Overlay headline collector.
Integrated into FastAPI's lifespan via start_scheduler() / stop_scheduler().
"""
import logging
logger = logging.getLogger(__name__)
_scheduler = None
def _get_scheduler():
global _scheduler
if _scheduler is None:
try:
from apscheduler.schedulers.asyncio import AsyncIOScheduler
_scheduler = AsyncIOScheduler(timezone="UTC")
except ImportError:
logger.warning("apscheduler not installed; overlay scheduling disabled")
return None
return _scheduler
async def _run_collect_job() -> None:
"""Scheduled job: collect Yahoo RSS headlines."""
from app.core.database import AsyncSessionLocal
from app.services.overlay.overlay_pipeline import OverlayPipeline
pipeline = OverlayPipeline()
async with AsyncSessionLocal() as db:
try:
counts = await pipeline.collect_all(db)
logger.info(f"[Scheduler] collect_all completed: {counts}")
except Exception as e:
logger.error(f"[Scheduler] collect_all failed: {e}")
def start_scheduler() -> None:
"""Start the APScheduler. Call from FastAPI lifespan startup."""
from app.core.config import settings
if not getattr(settings, "OVERLAY_ENABLED", True):
logger.info("Overlay disabled; scheduler not started")
return
sched = _get_scheduler()
if sched is None:
return
try:
from apscheduler.triggers.cron import CronTrigger
# Yahoo RSS collect: 23:30 UTC daily on weekdays (≈ 18:30 ET)
sched.add_job(
_run_collect_job,
trigger=CronTrigger(day_of_week="mon-fri", hour=23, minute=30, timezone="UTC"),
id="overlay_collect",
replace_existing=True,
misfire_grace_time=600,
)
sched.start()
logger.info("Overlay scheduler started (collect @ 23:30 UTC, weekdays)")
except Exception as e:
logger.error(f"Overlay scheduler start failed: {e}")
def stop_scheduler() -> None:
sched = _get_scheduler()
if sched and sched.running:
sched.shutdown(wait=False)
logger.info("Overlay scheduler stopped")