From b5e7c82b514700038147d64161c86f4c6943ef64 Mon Sep 17 00:00:00 2001 From: k Date: Fri, 8 May 2026 15:00:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(scheduler):=20trumpstruth=20poller=20never?= =?UTF-8?q?=20fires=20=E2=80=94=20APScheduler=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit next_run_time=None means "paused", not "default". The fallback poller was registered but never triggered, leaving the system on CNN archive only. Set explicit start time = now + half the poll interval so the two pollers offset and don't hit upstream simultaneously. Verified via /api/health/deep: trumpstruth.last_poll was null on the live server before this fix despite the poller having been deployed. Co-Authored-By: Claude Opus 4.7 --- app/main.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/main.py b/app/main.py index aa638ff..88d50a1 100644 --- a/app/main.py +++ b/app/main.py @@ -69,6 +69,11 @@ async def lifespan(app: FastAPI): # same external_id hash, so dedup is automatic. Whoever sees the post # first wins. Offset by half the interval so the two pollers don't # hammer the network at the same instant. + # Offset the fallback by half the interval so the two pollers don't hit + # upstream at the same instant. APScheduler treats next_run_time=None as + # "paused" (job never fires) — must be an actual datetime. + from datetime import datetime as _dt, timezone as _tz, timedelta as _td + offset = settings.truth_social_poll_seconds // 2 _scheduler.add_job( poll_trumpstruth, "interval", @@ -77,7 +82,7 @@ async def lifespan(app: FastAPI): id="trumpstruth_poll", max_instances=1, coalesce=True, - next_run_time=None, # APScheduler will pick a fresh slot + next_run_time=_dt.now(_tz.utc) + _td(seconds=offset), ) _scheduler.start() logger.info(